Introduction to the use of swfupload for phpcms module development

  • 2020-06-01 08:38:37
  • OfStack

After the formal contact with the development of phpcms module, I developed several functional modules and encountered the problem of needing to upload pictures in batches, so I began to explore the usage of swfupload in phpcms.

You can specify the image group directly in the content type that comes with phpcms. However, this image group function is not what I want to use. I need to upload 1 entire static html file

Able to find a way to upload the entire folder and retain the original file name.

The purpose is summarized as follows:

1. Do not change the file and directory structure of the system.

2. Realize the uploading function of multiple attachments.

3. You can get the name of the folder after uploading.

The attachment upload function is included in phpcms. I want to use the swfupload function, which is integrated with the attachment upload function of phpcms. All I have to do is pull it out and modify it.

Step 1, let's see how this is called.

First, open firebug in firefox browser and open the network panel. Find the button that swfupload calls out in phpcm. See what connection the system is requesting.


?m=attachment&c=attachments&a=swfupload&args=10,,1&module=&catid=&authkey=b756a93dea2e627293e88fa9d62af709&pc_hash=iXFbo1

We caught a string of such requests. We called the swfupload method in the attachements controller of the attachment module.

So let's go find this method in this controller in this module.

In phpcms/modoules/attachemet/attachemts php inside

Open it and see the code below


public function swfupload(){
        $grouplist = getcache('grouplist','member');
        if(isset($_POST['dosubmit'])){
      //if We're not going to look at what's in there . Because that's what happens after you upload it . We have to figure out how do we introduce it swfupload the .
        } else {
            if($this->isadmin==0 && !$grouplist[$this->groupid]['allowattachment']) showmessage(L('att_no_permission'));
            $args = $_GET['args'];// Get the parameter 
            $authkey = $_GET['authkey'];// Get the key 
            if(upload_key($args) != $authkey) showmessage(L('attachment_parameter_error'));// Verify the key 
            extract(getswfinit($_GET['args']));// Break up the parameter 
            $siteid = $this->get_siteid();// Get the website id
            $site_setting = get_site_setting($siteid);// Get the website Settings 
            $file_size_limit = sizecount($site_setting['upload_maxsize']*1024);// Allow upload size 
            $att_not_used = param::get_cookie('att_json');// Gets a list of unprocessed files 
            if(empty($att_not_used) || !isset($att_not_used)) $tab_status = ' class="on"';// If there is an unhandled set tag style of on
            if(!empty($att_not_used)) $div_status = ' hidden';// Otherwise hide the tag             
            $att = $this->att_not_used();// Gets a list of temporarily unprocessed files 
            include $this->admin_tpl('swfupload');// This place is the key . The template is loaded .
        }
    }

We left out the previous one, which is to handle the upload. I started with else. First, I verified whether the attachment is allowed to upload

Then get the swfupload parameter args from $_GET, then verify the key, and the key goes to parse args. Get the id of the website, get the Settings of the website, get the size of the attachments allowed to be uploaded, and get the list of unused attachments from cookie.

Set the various displays in the template. Last but not least, it USES the swfupload template. That is to say, I need to find this template.

Template here: phpcms/modules/attachment/templates/swfupload tpl. php

Open the template file. 1 heap of files have been introduced to the template file:


<?php $show_header = $show_validator = $show_scroll = 1; include $this->admin_tpl('header', 'attachment');?>
<link href="<?php echo JS_PATH?>swfupload/swfupload.css" rel="stylesheet" type="text/css" />
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/swfupload.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/fileprogress.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/handlers2.js"></script>
<script type="text/javascript">
<?php echo initupload($_GET['module'],$_GET['catid'],$args,$this->userid,$this->groupid,$this->isadmin)?>
</script>

The first is the introduction of the header file. I have a rough look in 1. It has jquery in it. It is a necessary file.

This is followed by the swfupload style file and the necessary JS. There is a system function called initupload, what exactly does this function do?

Don't underestimate this line. The entire swfupload configuration is here.

Let's go look for this function.

In phpcms/modules/attachment/functions/golable func. php found inside it. The code is as follows, the main role of this function is configuration swfupload this plug-in.


/* flash Upload initialization 
     *  Initialize the swfupload The parameters required for the uppass 
     * @param $module  The name of the module 
     * @param $catid  The column id
     * @param $args  Passing parameters 
     * @param $userid  The user id
     * @param $groupid  User groups id
     * @param $isadmin  Is it in administrator mode 
     */
    function initupload($module, $catid,$args, $userid, $groupid = '8', $isadmin = '0'){
        $grouplist = getcache('grouplist','member');
        if($isadmin==0 && !$grouplist[$groupid]['allowattachment']) return false;
        extract(getswfinit($args));
        $siteid = param::get_cookie('siteid');
        $site_setting = get_site_setting($siteid);
        $file_size_limit = $site_setting['upload_maxsize'];
        $sess_id = SYS_TIME;
        $swf_auth_key = md5(pc_base::load_config('system','auth_key').$sess_id);
        $init =  'var swfu = \'\';
        $(document).ready(function(){
        swfu = new SWFUpload({
            flash_url:"'.JS_PATH.'swfupload/swfupload.swf?"+Math.random(),
            upload_url:"'.APP_PATH.'index.php?m=attachment&c=attachments&a=swfupload&dosubmit=1",
            file_post_name : "Filedata",
            post_params:{"SWFUPLOADSESSID":"'.$sess_id.'","module":"'.$module.'","catid":"'.$_GET['catid'].'","userid":"'.$userid.'","siteid":"'.$siteid.'","dosubmit":"1","thumb_width":"'.$thumb_width.'","thumb_height":"'.$thumb_height.'","watermark_enable":"'.$watermark_enable.'","filetype_post":"'.$file_types_post.'","swf_auth_key":"'.$swf_auth_key.'","isadmin":"'.$isadmin.'","groupid":"'.$groupid.'"},
            file_size_limit:"'.$file_size_limit.'",
            file_types:"'.$file_types.'",
            file_types_description:"All Files",
            file_upload_limit:"'.$file_upload_limit.'",
            custom_settings : {progressTarget : "fsUploadProgress",cancelButtonId : "btnCancel"},
            button_image_url: "",
            button_width: 75,
            button_height: 28,
            button_placeholder_id: "buttonPlaceHolder",
            button_text_style: "",
            button_text_top_padding: 3,
            button_text_left_padding: 12,
            button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
            button_cursor: SWFUpload.CURSOR.HAND,
            file_dialog_start_handler : fileDialogStart,
            file_queued_handler : fileQueued,
            file_queue_error_handler:fileQueueError,
            file_dialog_complete_handler:fileDialogComplete,
            upload_progress_handler:uploadProgress,
            upload_error_handler:uploadError,
            upload_success_handler:uploadSuccess,
            upload_complete_handler:uploadComplete
            });
        })';
        return $init;
    }

Back to business. Let's look at the template swfupload.tpl.php

This template is controlled using 1 js < li > We can use firebug to find the id with the swfupload button we are looking for

That id is tab_swf_1

This is an div code as follows.


<div id="div_swf_1" class="content pad-10 <?php echo $div_status?>">
            <div>
                <div class="addnew" id="addnew">
                    <span id="buttonPlaceHolder"></span>
                </div>
                <input type="button" id="btupload" value="<?php echo L('start_upload')?>" onClick="swfu.startUpload();" />
                <div id="nameTip" class="onShow"><?php echo L('upload_up_to')?><font color="red"> <?php echo $file_upload_limit?></font> <?php echo L('attachments')?>,<?php echo L('largest')?> <font color="red"><?php echo $file_size_limit?></font></div>
                <div class="bk3"></div>
                <div class="lh24"><?php echo L('supported')?> <font style="font-family: Arial, Helvetica, sans-serif"><?php echo str_replace(array('*.',';'),array('',' , '),$file_types)?></font> <?php echo L('formats')?></div><input type="checkbox" id="watermark_enable" value="1" <?php if(isset($watermark_enable) &&$watermark_enable == 1) echo 'checked'?> onclick="change_params()"> <?php echo L('watermark_enable')?>
            </div>
            <div class="bk10"></div>
            <fieldset class="blue pad-10" id="swfupload">
            <legend><?php echo L('lists')?></legend>
            <ul class="attachment-list"  id="fsUploadProgress">
            </ul>
            </fieldset>
        </div>

Here we see that there is one span id which is buttonPlaceHolder and there is one line button_placeholder_id: "buttonPlaceHolder" in the configuration file. Obviously, when the page is loaded, the element id buttonPlaceHolder will be replaced by JS swfupload upload control.

The next step is to trigger the swf upload method after clicking on the file

The following code will be found in the code. This calls the swfu.startUpload () method. This method is defined in swfupload.js.


<input type="button" id="btupload" value="<?php echo L('start_upload')?>" onClick="swfu.startUpload();" />

So far, we have found a way to use the upload control of swfupload

How do I call this guy in my program

First of all, we need to introduce the necessary files into the template in which the control appears


<link href="<?php echo JS_PATH?>swfupload/swfupload.css" rel="stylesheet" type="text/css" />
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/swfupload.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/fileprogress.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/handlers2.js"></script>
<script type="text/javascript">
<?php echo initupload($_GET['module'],$_GET['catid'],$args,$this->userid,$this->groupid,$this->isadmin)?>
</script>

The code is shown above.

Then put this tag where we want to put swfupload in our template


<span id="buttonPlaceHolder"></span>
<input type="button" id="btupload" value="<?php echo L('start_upload')?>" onClick="swfu.startUpload();

So we've already introduced swfupload to where we need it, and then we'll be able to do things like upload.

But this can not meet our requirements. And there is a problem. Where did we upload the file to? Let's find out where did we upload the file to

There is this line in the configuration file (output with the initupload function)


upload_url:"'.APP_PATH.'index.php?m=attachment&c=attachments&a=swfupload&dosubmit=1",

This is an obvious indication that we've uploaded the file to the attachment module and the swfupload method in the attachments controller is handling it

This is the place that I didn't pay attention to before in if.

Take it out


if( $_POST['swf_auth_key'] != md5(pc_base::load_config('system','auth_key').$_POST['SWFUPLOADSESSID']) || ($_POST['isadmin']==0 && !$grouplist[$_POST['groupid']]['allowattachment'])) exit();
            pc_base::load_sys_class('attachment','',0);
            $attachment = new attachment($_POST['module'],$_POST['catid'],$_POST['siteid']);
            $attachment->set_userid($_POST['userid']);
            $aids = $attachment->upload('Filedata',$_POST['filetype_post'],'','',array($_POST['thumb_width'],$_POST['thumb_height']),$_POST['watermark_enable']);
            if($aids[0]) {
                $filename= (strtolower(CHARSET) != 'utf-8') ? iconv('gbk', 'utf-8', $attachment->uploadedfiles[0]['filename']) : $attachment->uploadedfiles[0]['filename'];
                if($attachment->uploadedfiles[0]['isimage']) {
                    echo $aids[0].','.$this->upload_url.$attachment->uploadedfiles[0]['filepath'].','.$attachment->uploadedfiles[0]['isimage'].','.$filename;
                } else {
                    $fileext = $attachment->uploadedfiles[0]['fileext'];
                    if($fileext == 'zip' || $fileext == 'rar') $fileext = 'rar';
                    elseif($fileext == 'doc' || $fileext == 'docx') $fileext = 'doc';
                    elseif($fileext == 'xls' || $fileext == 'xlsx') $fileext = 'xls';
                    elseif($fileext == 'ppt' || $fileext == 'pptx') $fileext = 'ppt';
                    elseif ($fileext == 'flv' || $fileext == 'swf' || $fileext == 'rm' || $fileext == 'rmvb') $fileext = 'flv';
                    else $fileext = 'do';
                    echo $aids[0].','.$this->upload_url.$attachment->uploadedfiles[0]['filepath'].','.$fileext.','.$filename;
                }
                exit;
            } else {
                echo '0,'.$attachment->error();
                exit;

There are a few important lines in this.

First it loads the system's attachment class and USES the methods inside.

The program has successfully done echo operation on the upload. The things returned are the number, the address after the upload, the extension name, and the file name.

Who are these things for? We have to go back to the configuration files.

There is a section in the configuration file which is the method that will be triggered by each event during the upload process.

We can see that one method is file_dialog_complete_handler:fileDialogComplete,

In fact, these have been upgraded to the category of swfupload. If you are interested, you can study them

Then we in phpcms/static/swfupload/handler js found inside this method.

After seeing the successful upload, the data from echo was parsed.

The method of parsing is as follows


function att_show(serverData,file)
{
    var serverData = serverData.replace(/<div.*?<\/div>/g,'');
    var data = serverData.split(',');
    var id = data[0];
    var src = data[1];
    var ext = data[2];
    var filename = data[3];
    if(id == 0) {
        alert(src)
        return false;
    }
    if(ext == 1) {
        var img = '<a href="javascript:;" onclick="javascript:att_cancel(this,'+id+',\'upload\')" class="on"><div class="icon"></div><img src="'+src+'" width="80" imgid="'+id+'" path="'+src+'" title="'+filename+'"/></a>';
    } else {
        var img = '<a href="javascript:;" onclick="javascript:att_cancel(this,'+id+',\'upload\')" class="on"><div class="icon"></div><img src="statics/images/ext/'+ext+'.png" width="80" imgid="'+id+'" path="'+src+'" title="'+filename+'"/></a>';
    }
    $.get('index.php?m=attachment&c=attachments&a=swfupload_json&aid='+id+'&src='+src+'&filename='+filename);
    $('#fsUploadProgress').append('<li><div id="attachment_'+id+'" class="img-wrap"></div></li>');
    $('#attachment_'+id).html(img);
    $('#att-status').append('|'+src);
    $('#att-name').append('|'+filename);
}

The purpose of this method is to add the attachment that we uploaded successfully to the id element for fsuuploadprogress, but we haven't found out where the file actually went

Here's the key. We have an instance of attachment's system class in the swfupload method

The actual upload of the attachment is implemented here. We call the upload method in attachment to realize the upload of the file.

This attachment file upload method in system class is phpcms libs/classes/attachment class. php inside

In this class we can find the upload method with a line like this


$this->savepath = $this->upload_root.$this->upload_dir.date('Y/md/');

This, of course, specifies the directory to upload to. The file name is obtained using the getname method.

This is where we clear our heads.

Here's how the system works

Start by referencing swfupload in the template (the configuration file is generated using the function)- > Upload file - > swfupload method in the attachment module (use the upload method in the attachment class of the system to loop upload attachments and return the results to the swfupload method)- > The result of the processing is returned to the page via the swfupload method (fileDialogComplete).

Above, we have implemented the introduction of swfupload into the template. However, the configuration files we used and the method of uploading attachments are all originally included in the system, which cannot realize the directory structure and file naming method I want.

To change.

We will create our own function in the functions folder in our module. We will name our function global.func.php so that the system will load our function via auto_load

In the attachment module functions folder, global.func.php, we copy the initupload function in global.func.php


upload_url:"'.APP_PATH.'index.php?m= The name of your module &c= The name of your controller &a= The name of your method &dosubmit=1",

The file will then be submitted to our controller and the method we wrote will be called

Then we will change the attachment class of the system and we will create an myattachment.class.php under the classes folder under our own module

Write a class of our own. To integrate the system's attachment class.(remember the private method copy.) we need to change a few lines.


function upload($field, $alowexts = '', $maxsize = 0, $overwrite = 0,$thumb_setting = array(), $watermark_enable = 1) {
        if(!isset($_FILES[$field])) {
            $this->error = UPLOAD_ERR_OK;
            return false;
        }
        if(empty($alowexts) || $alowexts == '') {
            $site_setting = $this->_get_site_setting($this->siteid);
            $alowexts = $site_setting['upload_allowext'];
        }
        $fn = $_GET['CKEditorFuncNum'] ? $_GET['CKEditorFuncNum'] : '1';
        $this->field = $field;
        $this->savepath = $this->upload_root.$this->upload_dir.date('Ymd');// Here we need to modify it . It can also be left unmodified . Specify the directory when we instantiate the class .
        $this->alowexts = $alowexts;
        $this->maxsize = $maxsize;
        $this->overwrite = $overwrite;
        $uploadfiles = array();
        $description = isset($GLOBALS[$field.'_description']) ? $GLOBALS[$field.'_description'] : array();
        if(is_array($_FILES[$field]['error'])) {
            $this->uploads = count($_FILES[$field]['error']);
            foreach($_FILES[$field]['error'] as $key => $error) {
                if($error === UPLOAD_ERR_NO_FILE) continue;
                if($error !== UPLOAD_ERR_OK) {
                    $this->error = $error;
                    return false;
                }
                $uploadfiles[$key] = array('tmp_name' => $_FILES[$field]['tmp_name'][$key], 'name' => $_FILES[$field]['name'][$key], 'type' => $_FILES[$field]['type'][$key], 'size' => $_FILES[$field]['size'][$key], 'error' => $_FILES[$field]['error'][$key], 'description'=>$description[$key],'fn'=>$fn);
            }
        } else {
            $this->uploads = 1;
            if(!$description) $description = '';
            $uploadfiles[0] = array('tmp_name' => $_FILES[$field]['tmp_name'], 'name' => $_FILES[$field]['name'], 'type' => $_FILES[$field]['type'], 'size' => $_FILES[$field]['size'], 'error' => $_FILES[$field]['error'], 'description'=>$description,'fn'=>$fn);
        }
        if(!dir_create($this->savepath)) {
            $this->error = '8';
            return false;
        }
        if(!is_dir($this->savepath)) {
            $this->error = '8';
            return false;
        }
        @chmod($this->savepath, 0777);
        if(!is_writeable($this->savepath)) {
            $this->error = '9';
            return false;
        }
        if(!$this->is_allow_upload()) {
            $this->error = '13';
            return false;
        }
        $aids = array();
        foreach($uploadfiles as $k=>$file) {
            $fileext = fileext($file['name']);
            if($file['error'] != 0) {
                $this->error = $file['error'];
                return false;
            }
            if(!preg_match("/^(".$this->alowexts.")$/", $fileext)) {
                $this->error = '10';
                return false;
            }
            if($this->maxsize && $file['size'] > $this->maxsize) {
                $this->error = '11';
                return false;
            }
            if(!$this->isuploadedfile($file['tmp_name'])) {
                $this->error = '12';
                return false;
            }
            //$temp_filename = $this->getname($fileext);// The name is here . We need to revise it 
       $temp_filename = $file['tmp_name'].$fileext; // Change to the original system file name .
       $savefile = $this->savepath.$temp_filename; $savefile = preg_replace("/(php|phtml|php3|php4|jsp|exe|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i", "_\\1\\2", $savefile); $filepath = preg_replace(new_addslashes("|^".$this->upload_root."|"), "", $savefile); if(!$this->overwrite && file_exists($savefile)) continue; $upload_func = $this->upload_func; if(@$upload_func($file['tmp_name'], $savefile)) { $this->uploadeds++; @chmod($savefile, 0644); @unlink($file['tmp_name']); $file['name'] = iconv("utf-8",CHARSET,$file['name']); $uploadedfile = array('filename'=>$file['name'], 'filepath'=>$filepath, 'filesize'=>$file['size'], 'fileext'=>$fileext, 'fn'=>$file['fn']); $thumb_enable = is_array($thumb_setting) && ($thumb_setting[0] > 0 || $thumb_setting[1] > 0 ) ? 1 : 0; $image = new image($thumb_enable,$this->siteid); if($thumb_enable) { $image->thumb($savefile,'',$thumb_setting[0],$thumb_setting[1]); } if($watermark_enable) { $image->watermark($savefile, $savefile); } $aids[] = $this->add($uploadedfile); } } return $aids; }

Note: here we can set up MY_attachment. php under the attachment module of the system, but this will affect the system's attachment upload function.

In our own controller, we need to load our own class at this point.


pc_base::load_app_class(' Your module name ','',0);

The rest of the operations can be modified by referring to the swfupload method in the attachments controller under the attachment module of the system.

At this point, I have achieved my goal. Without changing the system file directory, I have completed the file upload function I want.


Related articles: