WordPress File Upload - Version 4.16.0

Version Description

  • visual editor edit button misalignment fixed
  • corrected echo problem when recording from webcam with sound
Download this release

Release Info

Developer nickboss
Plugin Icon 128x128 WordPress File Upload
Version 4.16.0
Comparing to
See all releases

Code changes from version 4.15.0 to 4.16.0

css/wordpress_file_upload_adminstyle.css CHANGED
@@ -1 +1 @@
1
- div.wfu_shortcode_container{display:inline-block;position:relative;width:50%;padding:0;margin:0;background:0 0;border:none}textarea.wfu_shortcode{width:100%}div.wfu_container{margin-top:10px}div.wfu_help_container{display:inline-block;position:relative;top:4px;padding:0;margin:0;background:0 0;border:none}div.wfu_help_container img{visibility:hidden}table.wfu_main_table th:hover div.wfu_help_container img{visibility:visible}table.wfu_inner_table th:hover div.wfu_help_container img{visibility:visible}div.wfu_restore_container{display:inline-block;position:relative;top:4px;padding:0;margin:0;background:0 0;border:none}div.wfu_restore_container img{visibility:hidden}table.wfu_main_table th:hover div.wfu_restore_container img{visibility:visible}table.wfu_inner_table th:hover div.wfu_restore_container img{visibility:visible}div.wfu_td_div{display:block;position:relative;width:100%;height:100%;padding:0;margin:0;background:0 0;border:none}div.wfu_container input.wfu_long_text{width:100%}div.wfu_container input.wfu_short_text{width:60px}div.wfu_container input{width:200px}div.wfu_container input[type=checkbox]{width:auto}div.wfu_container textarea{width:100%}table.wfu_main_table{table-layout:fixed}table.wfu_main_table tr:nth-child(odd){background-color:#f4f4f4}table.wfu_main_table tr:nth-child(even){background-color:transparent}table.wfu_main_table table.wfu_inner_table tr{background-color:transparent}table.wfu_main_table th{width:17%}table.wfu_main_table td:nth-child(2){width:33%}table.wfu_main_table td:nth-child(3){width:50%}table.wfu_main_table table.wfu_inner_table th{width:34%}table.wfu_main_table table.wfu_inner_table td:nth-child(2){width:66%}table.wfu_main_table tr.wfu_subcategory{background-color:#ddd}table.wfu_main_table tr.wfu_subcategory>th{padding-top:0;padding-bottom:0}select.wfu_variable{padding:0;margin:0;height:auto;font-size:smaller;background-color:#ddd;border:1px solid #ccc;color:#333;-webkit-border-radius:5px;-moz-border-radius:5px;-khtml-border-radius:5px;border-radius:5px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}span.wfu_variable{padding:1px;margin:0;font-size:smaller;background-color:#ddd;border:1px solid #ccc;color:#333;-webkit-border-radius:5px;-moz-border-radius:5px;-khtml-border-radius:5px;border-radius:5px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}div.wfu_date_container{display:inline-block;position:relative;width:auto;height:100%;padding:0;margin:0;background:0 0;border:none}.wfu_datereset_button{position:absolute;right:4px;top:0;bottom:0;margin:auto 0;opacity:.5}.wfu_datereset_button:hover{opacity:1}span.wfu_ptext_span{display:inline-block;width:60px}select.wfu_select_folders{height:auto;min-width:75%}select.wfu_select_folders_empty{font-style:italic;color:silver}.ftpinfo_header{white-space:nowrap}.ftpinfo_text{width:calc(100% - 7ch - 6px)!important}@media screen and (max-width:782px){.ftpinfo_text{width:100%!important}}.ftpinfo_tool.hidden{display:none}.ftpinfo_btn{display:inline-block;width:7ch}.ftpinfo_label{font-weight:600;margin-right:10px;display:inline-block;width:10ch}.ftpinfo_value{vertical-align:middle}.ftpinfo_error{background-color:#fffacd!important;color:red!important}div.wfu_subfolders_inner_shadow{position:absolute;width:100%;height:100%;padding:0;margin:0;border:none;background-color:rgba(255,255,255,.8)}option.wfu_select_folders_option_default{color:#00f}div.wfu_subfolder_nav_container{width:40px;margin:0;padding:0;border:none;background:0 0;display:inline-block;vertical-align:top}table.wfu_subfolder_nav{table-layout:fixed;width:100%;margin:0;padding:0;border:none;background:0 0;border-spacing:1px}table.wfu_subfolder_nav tr{margin:0;padding:0;border:none;background:0 0}table.wfu_subfolder_nav td{margin:0;padding:0!important;border:none;background:0 0;font-size:small;line-height:1;text-align:center}table.wfu_subfolder_nav button.button{margin:0;padding:0;width:17px;font-size:smaller;height:18px;line-height:1;color:#000;font-weight:700}table.wfu_subfolder_nav button.button:disabled{color:silver}.button.wfu_subfolder_nav_pressed,.button.wfu_subfolder_nav_pressed:focus,.button.wfu_subfolder_nav_pressed:hover{background:#4169e1}div.wfu_subfolder_tools_container{width:75%;margin:0;padding:0;border:none;background:0 0}table.wfu_subfolder_tools{table-layout:fixed;width:100%;margin:0;padding:0;border:none;background:0 0}table.wfu_subfolder_tools tr{margin:0;padding:0;border:none;background:0 0}table.wfu_subfolder_tools td{margin:0;padding:0;border:none;background:0 0;font-size:smaller}table.wfu_subfolder_tools td div{margin:0;padding:0;border:none;background:0 0;position:relative}table.wfu_subfolder_tools label{display:block;padding:0;margin:0;line-height:1}table.wfu_subfolder_tools input{width:100%;padding:0;margin:0}table.wfu_subfolder_tools input:disabled{width:100%;padding:0;margin:0;color:silver}table.wfu_subfolder_tools button.button{margin:0;padding:1px 0 0 0;width:17px;font-size:smaller;height:17px;line-height:1;position:absolute;bottom:2px}table.wfu_subfolder_tools button.button:disabled{color:silver}table.wfu_subfolder_tools button.button:disabled img{opacity:.4}.wfu_subfolder_tools_disabled{color:silver}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container{position:absolute;width:150px;height:150px;margin:0;padding:0;z-index:100;border:1px solid silver;box-shadow:1px 1px 2px;background-color:#fff;font-size:inherit}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container table{table-layout:fixed;width:100%;height:100%;border:none;background:#eee;margin:0;padding:0;border-spacing:0;font-size:inherit}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container tr{border:none;background:0 0;margin:0;padding:0;font-size:inherit}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td{border:none;background:0 0;margin:0;padding:2px;line-height:0;overflow:hidden;font-size:inherit}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div{position:relative;border:none;background:0 0;margin:0;padding:0;width:100%;height:100%;display:inline-block;line-height:1}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div button.button{font-size:inherit;line-height:1;height:17px;padding:4px;position:relative;width:auto;margin:0;bottom:auto}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container select{width:100%;height:100%;top:0;bottom:0;position:absolute;margin:0}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container label{color:#222;font-weight:700;position:absolute;top:0;bottom:0;height:10px;margin:auto}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div button.button.wfu_folder_browser_cancel{width:17px;height:17px;position:absolute;right:0;top:0;margin:0;padding:0}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div div.wfu_folder_browser_loading_container{position:absolute;width:100%;height:100%;top:0;bottom:0;margin:0;padding:0;background-color:rgba(255,255,255,.9);text-align:center}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div div.wfu_folder_browser_loading_container label{position:relative;display:block}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div div.wfu_folder_browser_loading_container img{position:relative}.button.wfu_folder_browser_cancel img{vertical-align:top;margin-top:2px}div.wfu_mchecklist_container{display:inline-block;border:1px solid #ddd;border-radius:4px;padding:4px}div.wfu_mchecklist_item{display:inline-block}div.wfu_mchecklist_item label{vertical-align:baseline;margin-left:4px;cursor:default}div.wfu_mchecklist_item input:disabled+label{color:gray}div.wfu_mchecklist_item div{margin-left:4px}div.wfu_mchecklist_item:hover img{visibility:visible}div.wfu_mchecklist_checkall{display:inline-block;vertical-align:top;margin:0 0 0 10px}div.wfu_bloglist_checkbtn,div.wfu_postlist_checkbtn,div.wfu_rolelist_checkbtn,div.wfu_userlist_checkbtn{display:inline-block;vertical-align:top;margin:0 0 0 10px}table.wfu_bloglist_container,table.wfu_postlist_container,table.wfu_rolelist_container,table.wfu_stringmatch_container,table.wfu_userlist_container{border:none;background:0 0;margin:0;padding:0;border-spacing:0}table.wfu_bloglist_container tr:nth-child(odd),table.wfu_postlist_container tr:nth-child(odd),table.wfu_rolelist_container tr:nth-child(odd),table.wfu_userlist_container tr:nth-child(odd){border:none;background:0 0;background-color:transparent;margin:0;padding:0}table.wfu_bloglist_container td,table.wfu_postlist_container td,table.wfu_rolelist_container td,table.wfu_stringmatch_container td,table.wfu_userlist_container td{width:1%;border:none;background:0 0;margin:0;padding:0;vertical-align:top}table.wfu_postlist_container td{padding-right:20px}table.wfu_postlist_container td:last-child{padding-right:0}div.wfu_postlist_header{padding:0 10px}div.wfu_postlist_selectall{float:right}div.wfu_shadow{position:absolute;width:100%;height:100%;left:0;top:0;margin:0;padding:0;background-color:#fff;z-index:10;-moz-opacity:.6;-khtml-opacity:.6;opacity:.6}table.wfu_main_table tr:nth-child(odd) div.wfu_shadow{background-color:#f4f4f4}div.wfu_onoff_container_off,div.wfu_onoff_container_on{display:inline-block;position:relative;padding:2px;border:1px solid #aaa;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px;background:#066dab;background:-moz-linear-gradient(top,#066dab 0,#c5deea 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#066dab),color-stop(100%,#c5deea));background:-webkit-linear-gradient(top,#066dab 0,#c5deea 100%);background:-o-linear-gradient(top,#066dab 0,#c5deea 100%);background:-ms-linear-gradient(top,#066dab 0,#c5deea 100%);background:linear-gradient(to bottom,#066dab 0,#c5deea 100%)}span.wfu_onoff_text{width:30px;display:inline-block;text-align:center;color:#fff}div.wfu_onoff_slider{position:absolute;margin:0;width:31px;top:0;bottom:0;border:1px solid #fff;-webkit-border-radius:2px;-moz-border-radius:2px;-khtml-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 2px;-webkit-box-shadow:0 0 2px;box-shadow:0 0 2px;background:#ccc;background:-moz-linear-gradient(top,#ccc 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ccc),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ccc 0,#fff 100%);background:-o-linear-gradient(top,#ccc 0,#fff 100%);background:-ms-linear-gradient(top,#ccc 0,#fff 100%);background:linear-gradient(to bottom,#ccc 0,#fff 100%)}div.wfu_onoff_container_on div.wfu_onoff_slider{left:50%}div.wfu_onoff_container_off div.wfu_onoff_slider{left:0}@-webkit-keyframes set_on{from{left:0}to{left:50%}}@-moz-keyframes set_on{from{left:0}to{left:50%}}@-o-keyframes set_on{from{left:0}to{left:50%}}@keyframes set_on{from{left:0}to{left:50%}}div.wfu_placements_wrapper{display:block;position:relative;margin:0;padding:0;background:0 0;border:none}div.wfu_placements_container{display:inline-block;position:relative;width:100%;height:300px;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px;padding:0;overflow:scroll;font-size:0;line-height:0;white-space:nowrap}div.wfu_componentlist_container{display:inline-block;position:absolute;width:auto;height:auto;top:0;left:100%;background:0 0;border:none;margin:0 0 0 20px;padding:0;z-index:1;white-space:nowrap}div.wfu_component_box_container{display:inline-block;position:relative;width:80px;height:30px;background-color:transparent;border:1px solid transparent;padding:4px;margin:0;cursor:default}div.wfu_component_box_base{display:block;position:absolute;width:80px;height:30px;left:-1px;top:-1px;background-color:#ddd;border:1px solid #bbb;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px;padding:4px;cursor:default;font-size:12px;line-height:1;-moz-opacity:.4;-khtml-opacity:.4;opacity:.4;white-space:normal}div.wfu_component_box{display:inline-block;position:relative;width:80px;height:30px;background-color:#ddd;border:1px solid #bbb;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px;padding:4px;cursor:default;font-size:12px;line-height:1;z-index:1;white-space:normal}div.wfu_component_box_inner{display:table;width:100%;height:100%}div.wfu_component_box_label{display:table-cell;text-align:center;vertical-align:middle}div.wfu_component_box_index{background-color:coral;padding:1px;float:right;border-radius:10px}div.wfu_inbase{display:block;position:absolute;left:-1px;top:-1px}div.wfu_component_box:hover{background-color:#eee;border:1px solid #bbb}div.wfu_component_box_selected{background-color:#aaa;border:1px solid #bbb}div.wfu_component_box_dragged{-moz-opacity:.4;-khtml-opacity:.4;opacity:.4}div.wfu_component_separator_ver{display:inline-block;position:relative;width:8px;height:26px;background-color:transparent;border:1px solid transparent;margin:6px -8px;padding:0 8px;cursor:default;z-index:1}div.wfu_component_separator_hor{display:block;position:relative;width:100%;height:8px;background-color:transparent;border:1px solid transparent;margin:-8px 0;padding:8px 0;cursor:default;z-index:1}div.wfu_component_bar_hor{position:absolute;width:auto;height:4px;left:10px;right:0;background-color:silver;border:none;margin:11px 0 0 0;padding:0;display:none}div.wfu_component_bar_ver{position:absolute;width:4px;height:40px;background-color:silver;border:none;margin:-6px 0 0 11px;padding:0;display:none}div.wfu_componentlist_dragdrop{position:absolute;width:100%;height:100%;left:0;top:0;background-color:#f8f8f8;border:4px dashed #aaa;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;z-index:2;-moz-opacity:.7;-khtml-opacity:.7;opacity:.7}div.wfu_componentlist_dragdrop_dragover{border:4px dashed #555}div.wfu_formdata_container,div.wfu_userdata_container{display:block;position:relative;width:100%;height:100%;padding:0;margin:0;background:0 0;border:none}label.wfu_formdata_label{margin-right:6px}.wfu_formdata_props{padding-left:20px}div.wfu_formdata_action,div.wfu_userdata_action{display:inline-block;position:relative;top:2px;width:16px;height:16px;padding:0;margin:0;background:0 0;text-align:center;border:1px solid transparent;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}div.wfu_formdata_action:hover,div.wfu_userdata_action:hover{border:1px solid #aaa}div.wfu_formdata_action.wfu_formdata_action_disabled:hover,div.wfu_userdata_action.wfu_userdata_action_disabled:hover{border:1px solid transparent}div.wfu_formdata_action>img,div.wfu_userdata_action>img{width:12px;height:12px}div.wfu_formdata_action_disabled>img,div.wfu_userdata_action_disabled>img{-moz-opacity:.4;-khtml-opacity:.4;opacity:.4}div.wfu_formdata_line_container,div.wfu_userdata_line{display:block;position:relative;padding:0;margin:0;background:0 0;border:none;white-space:nowrap}table.wfu_formdata_props_table{background:0 0;border:none;padding:0}table.wfu_formdata_props_table td,table.wfu_main_table table.wfu_inner_table table.wfu_formdata_props_table td{background:0 0;border:none;padding:0;width:auto}table.wfu_formdata_props_table td.wfu_formdata_props,table.wfu_main_table table.wfu_inner_table table.wfu_formdata_props_table td.wfu_formdata_props{padding-left:20px}table.wfu_main_table td,table.wfu_main_table th{padding-top:15px}@media screen and (max-width:782px){.wfumain table.form-table td{width:100%!important}.wfumain .wp-list-table td[data-colname=Shortcode]{padding-left:8px!important}.wfumain .wp-list-table td[data-colname=Shortcode]:before{position:relative!important;margin-left:-8px!important;content:'Shortcode:'!important}div.wfu_shortcode_container{width:100%}table.wfu_main_table table.wfu_inner_table th,table.wfu_main_table th{width:50%}table.wfu_main_table table.wfu_inner_table td,table.wfu_main_table table.wfu_inner_table td:nth-child(2),table.wfu_main_table table.wfu_inner_table td:nth-child(3),table.wfu_main_table td,table.wfu_main_table td:nth-child(2),table.wfu_main_table td:nth-child(3){width:100%}#wpbody table.wfu_main_table select{height:auto!important}div.wfu_componentlist_container{position:relative;left:0}select.wfu_select_folders{width:calc(100% - 50px)!important;display:inline-block!important}table.wfu_formdata_props_table tbody tr:first-child td{display:table-cell}table.wfu_formdata_props_table tbody tr:first-child td:nth-child(2){padding-left:10px}.CodeMirror{width:100%!important}}div.wfu_color_container{display:block;position:relative;padding:0;margin:0;background:0 0;border:none;white-space:nowrap;z-index:1}input[type=text].wp-color-picker{width:75px}input[type=button].wp-picker-clear{width:62px}span.wfu_save_label{background-color:#f0f8ff;color:#32cd32;border-radius:6px;padding:1px 2px;box-shadow:1px 1px 1px;font-size:smaller;opacity:0}span.wfu_save_label_fail{background-color:beige;color:#f08080;border-radius:6px;padding:1px 2px;box-shadow:1px 1px 1px;font-size:smaller;opacity:0}div.wfu_global_dialog_container{position:fixed;width:100%;height:100%;top:0;left:0;margin:0;padding:0;border:none;background:0 0;z-index:1;display:none}table.wfu_main_table table.wfu_columns_container{border:none;background:0 0;margin:0;padding:0;border-spacing:0}table.wfu_main_table table.wfu_columns_container tr{background:0 0}table.wfu_main_table table.wfu_columns_container td{border:none;background:0 0;margin:0;padding:0;vertical-align:top;width:auto}table.wfu_main_table table.wfu_columnprops_container{border:none;background:0 0;margin:0;padding:6px;border-spacing:0;width:100%;box-shadow:0 0 1px #aaa}table.wfu_main_table table.wfu_columnprops_container tr{background:0 0}table.wfu_main_table table.wfu_columnprops_container td{border:none;background:0 0;margin:0;padding:0;vertical-align:middle;width:auto}table.wfu_main_table table.wfu_columnprops_container_disabled label{color:#ccc}table.wfu_main_table table.wfu_columnprops_container label.wfu_columnprops_label_disabled{color:#ccc}button.wfu_columns_addbutton{font-size:smaller}option.wfu_columns_item_required{color:gray}option.wfu_columns_item_defaultsort{text-decoration:underline}@font-face{font-family:wfu-icons;src:url(../images/fonts/wfu-icons.eot?xnqdfz);src:url(../images/fonts/wfu-icons.eot?xnqdfz#iefix) format('embedded-opentype'),url(../images/fonts/wfu-icons.ttf?xnqdfz) format('truetype'),url(../images/fonts/wfu-icons.woff?xnqdfz) format('woff'),url(../images/fonts/wfu-icons.svg?xnqdfz#wfu-icons) format('svg');font-weight:400;font-style:normal}.wfu-dashicons-media-external:before{font-family:wfu-icons;content:"\e900"}.wfu-dashicons-ftp:before{font-family:wfu-icons;content:"\e901"}.wfu-uploadedfiles .wfu-dashicons-after{margin-left:4px}.wfu-uploadedfiles .wfu-dashicons-hidden{display:none}.wfu-uploadedfiles .wfu-properties.wfu-clicked,.wfu-uploadedfiles .wfu-properties:hover{color:#00f}.wfu-uploadedfiles .wfu_unread{box-shadow:4px 0 0 inset #0f0;font-weight:700}.wfu-uploadedfiles .wfu-remarks-container:before{content:'-';width:0;display:inline-block;overflow:hidden}.wfu-adminbrowser .wfu-highlighted{box-shadow:0 -1000px 0 inset rgba(0,255,0,.2)}.wfu-historylog .wfu-highlighted{box-shadow:0 -1000px 0 inset rgba(0,255,0,.2)}.wfu_cleanlog_tr{display:none}.wfu_cleanlog_tr td{margin-top:0;padding-top:0}.wfu_selectdate_container,.wfu_selectdates_container,.wfu_selectperiod_container{display:none}.wfu_buttons_container,.wfu_includefiles_container,.wfu_selectdate_container,.wfu_selectdates_container,.wfu_selectperiod_container{margin-top:10px}.wfu_selectdate_container input[type=text],.wfu_selectdates_container input[type=text]{width:8em;text-align:center}.wfu_selectperiod_container input[type=number]{width:4em}.wfu_includefiles_container label{font-size:80%;opacity:.5}.wfu_includefiles_container input[type=checkbox]{transform:scale(.8,.8)}.wfu_buttons_container .button,.wfu_buttons_container .wfu_cleanlog_error,.wfu_includefiles_container input[type=checkbox],.wfu_includefiles_container label,.wfu_selectdate_container input[type=text],.wfu_selectdate_container label,.wfu_selectdates_container input[type=text],.wfu_selectdates_container label,.wfu_selectperiod_container input[type=number],.wfu_selectperiod_container label,.wfu_selectperiod_container select{vertical-align:middle}.wfu_cleanlog_proceed.disabled{pointer-events:none}.wfu_cleanlog_error{color:red;font-size:small}.wfu_cleanlog_error:before{content:'!';font-weight:700;margin-right:2px}.wfu_cleanlog_error.hidden{display:none}.wfu_conop_header,.wfu_pdop_header{transition:.4s;padding:6px}.wfu_conop_header label,.wfu_pdop_header label{font-weight:700;cursor:default}.wfu_conop_header.atomic label,.wfu_pdop_header.atomic label{font-weight:400}.wfu_consent_logactions,.wfu_consent_operations,.wfu_consent_permissions,.wfu_consent_questions,.wfu_consent_users,.wfu_plugin_operations{display:none}.wfu_pdheader_button{color:#777;padding:2px;border:1px solid gray;border-radius:1em;width:1em;height:1em;text-align:center;vertical-align:middle;position:relative;cursor:pointer;display:inline-block;font-size:smaller}.wfu_pdheader_button:after{content:'\02795';position:absolute;left:0;right:0;top:0;bottom:0;margin:auto}.wfu_pdheader_button.expanded:after{content:'\02796'}.wfu_conop_topmost_panel,.wfu_pdop_topmost_panel{margin-left:40px;overflow:hidden}.wfu_conop_panel,.wfu_pdop_panel{margin-left:40px;display:none;overflow:hidden}.wfu_conop_level_1,.wfu_pdop_level_1{padding:10px;font-size:larger}.wfu_conop_level_2,.wfu_pdop_level_2{padding:6px;font-size:smaller}.wfu_conop_level_3,.wfu_pdop_level_3{padding:2px}.wfu_conop_level_4,.wfu_pdop_level_4{padding:2px}.wfu_conop_level_5,.wfu_pdop_level_5{padding:2px}.wfu_conop_header:hover,.wfu_pdop_header:hover{background-color:rgba(0,0,0,.2)}input[type=checkbox].wfu_conop_selector,input[type=checkbox].wfu_pdop_selector{-webkit-appearance:checkbox}.wfu_conop_button,.wfu_pdop_button{color:#777;float:right;padding:2px;border:1px solid gray;border-radius:4px;width:1em;height:1em;text-align:center;position:relative;cursor:pointer;display:none}.wfu_conop_button:after,.wfu_pdop_button:after{content:'\02795';position:absolute;left:0;right:0;top:0;bottom:0;margin:auto;font-size:smaller}.wfu_conop_button.expanded:after,.wfu_pdop_button.expanded:after{content:'\02796'}.wfu_conop_header:hover .wfu_conop_button,.wfu_pdop_header:hover .wfu_pdop_button{display:block}input[type=checkbox].wfu_conop_selector,input[type=checkbox].wfu_pdop_selector{margin:0 0 0 4px}.wfu_conquestions_operations{margin-top:20px;margin-left:40px}.wfu_conquestions_operations label{display:block;font-size:larger;font-weight:700}.wfu_conquestions_oppanel{background-color:#fff;padding:10px;display:inline-block;margin-top:10px}.wfu_conquestions_optable{border-collapse:collapse}.wfu_conquestions_optable tbody tr:hover{background-color:rgba(0,0,0,.1)}.wfu_conquestions_optable td{cursor:default}.wfu_conquestions_optable td:not(:first-child){text-align:center}.wfu_op_unassigned{background-color:#ffdb99}.wfu_conquestions_optable tbody tr.wfu_op_unassigned:hover{background-color:#e6c58a}.wfu_op_unassigned .wfu_conquestions_opinv,.wfu_op_unassigned .wfu_conquestions_opsel{background-color:#ffdb99}.wfu_conquestions_optable tbody tr.wfu_op_unassigned:hover .wfu_conquestions_opinv,.wfu_conquestions_optable tbody tr.wfu_op_unassigned:hover .wfu_conquestions_opsel{background-color:#e6c58a}.wfu_conquestions_opsel.wfu_forced_selection{opacity:.5}.wfu_frozen{pointer-events:none}.wfu_conquestions_container{margin-top:20px;margin-left:40px}.wfu_conquestion_header{font-size:larger}.wfu_conquestion_subcontainer{padding:10px}.wfu_conquestion_headerlabel{font-weight:700}.wfu_conquestion_tools{float:right}.wfu_conquestion_itemprops,.wfu_conquestion_itemspreview,.wfu_conquestion_mainprops{display:table-cell;position:relative;border:1px solid silver;padding:4ex 10px 10px 10px;vertical-align:top;min-width:10em;min-height:4ex;resize:both;overflow:auto}.wfu_conquestion_itempropstitle,.wfu_conquestion_itemspreviewtitle,.wfu_conquestion_mainpropstitle{position:absolute;top:0;left:0;height:3ex;font-size:inherit;text-align:center;width:100%;background-color:rgba(0,0,0,.1)}.wfu_conquestion_displayedtitle,.wfu_conquestion_groupedlabel,.wfu_conquestion_labellabel,.wfu_conquestion_labellocationlabel,.wfu_conquestion_matrixlabel,.wfu_conquestion_preselectedlabel,.wfu_conquestion_titlelabel,.wfu_conquestion_titlelocationlabel,.wfu_conquestion_typelabel,.wfu_conquestion_visiblelabel{display:block}.wfu_conquestion_labeltext,.wfu_conquestion_titletext{width:100%}.wfu_conquestion_matrix_x,.wfu_conquestion_matrix_y{width:4em;text-align:center}.wfu_conquestion_matrixsep{width:1em;display:inline-block;text-align:center}.wfu_empty_label{font-style:italic}.wfu_conquestion_itemtable td:hover{background-color:rgba(0,0,0,.1)}.wfu_conquestion_itemcontainer{opacity:.5}.wfu_item_selected{background-color:rgba(0,0,0,.2)}.wfu_item_assigned{color:#00f}.wfu_item_visible{opacity:1}.wfu_conquestion_btn{display:inline-block;position:relative;width:16px;height:16px;padding:0;margin:0;background:0 0;text-align:center;border:1px solid transparent;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}div.wfu_conquestion_btn:hover{border:1px solid #aaa}.wfu_conquestion_btn>img{width:12px;height:12px;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto}div.wfu_conquestion_btn.wfu_tool_disabled:hover{border:1px solid transparent}.wfu_conquestion_btn.wfu_tool_disabled>img{opacity:.4}.wfu_permissions_topmost_panel{margin-left:40px}.wfu_permissions_panel{background-color:#fff;padding:10px;display:inline-block;margin-top:20px}.wfu_perm_container{padding-right:20px}.wfu_location_cell{text-align:center}.wfu_perm_level_1{padding-left:0}.wfu_perm_level_2{padding-left:20px}.wfu_perm_level_3{padding-left:40px}.wfu_permissions_table{border-collapse:collapse}.wfu_permissions_table td:nth-child(n+2),.wfu_permissions_table tr:nth-child(2) th{border-left:1px solid rgba(0,0,0,.1)}.wfu_perm_row:hover{background-color:rgba(0,0,0,.1)}.wfu_perm_button{color:#777;border:1px solid gray;width:1.5ex;height:1.5ex;text-align:center;position:relative;cursor:pointer;display:inline-block;vertical-align:middle}.wfu_perm_button:after{content:'+';position:absolute;left:0;right:0;top:-.75ex;bottom:0;margin:auto}.wfu_perm_button:hover{color:#000}.wfu_perm_button.expanded:after{content:'-'}input[type=checkbox].wfu_location_selector{-webkit-appearance:checkbox;margin:0}.wfu_logactions_topmost_panel{margin-left:40px}.wfu_logactions_panel{background-color:#fff;padding:10px;display:inline-block;margin-top:20px}.wfu_log_container{padding-right:20px}.wfu_entity_cell{text-align:center}.wfu_log_level_1{padding-left:0}.wfu_log_level_2{padding-left:20px}.wfu_log_level_3{padding-left:40px}.wfu_logactions_table{border-collapse:collapse}.wfu_logactions_table td:nth-child(n+2),.wfu_logactions_table tr:nth-child(2) th{border-left:1px solid rgba(0,0,0,.1)}.wfu_log_row:hover{background-color:rgba(0,0,0,.1)}.wfu_log_button{color:#777;border:1px solid gray;width:1.5ex;height:1.5ex;text-align:center;position:relative;cursor:pointer;display:inline-block;vertical-align:middle}.wfu_log_button:after{content:'+';position:absolute;left:0;right:0;top:-.75ex;bottom:0;margin:auto}.wfu_log_button:hover{color:#000}.wfu_log_button.expanded:after{content:'-'}input[type=checkbox].wfu_entity_selector{-webkit-appearance:checkbox;margin:0}.wfu_pdusers_topmost_panel{margin-top:20px;margin-left:40px}.wfu_pdusers_topmost_panel>label{display:block;font-size:larger;font-weight:700}.wfu_pdusers_rolepanel,.wfu_pdusers_userpanel{margin-top:20px;margin-bottom:20px}.wfu_pdusers_roles_container,.wfu_pdusers_users_container{display:inline-block}.wfu_pdusers_roles_leftpanel,.wfu_pdusers_roles_midpanel,.wfu_pdusers_roles_rightpanel,.wfu_pdusers_users_leftpanel,.wfu_pdusers_users_midpanel,.wfu_pdusers_users_rightpanel{display:table-cell;position:relative}.wfu_pdusers_roles_leftpanel,.wfu_pdusers_roles_rightpanel{height:200px;min-width:100px}.wfu_pdusers_users_leftpanel,.wfu_pdusers_users_rightpanel{height:100px;min-width:100px}.wfu_pdusers_roles_leftpanel,.wfu_pdusers_users_leftpanel{padding:10px 10px 10px 0}.wfu_pdusers_roles_midpanel,.wfu_pdusers_users_midpanel{padding:10px 0;vertical-align:top}.wfu_pdusers_roles_rightpanel,.wfu_pdusers_users_rightpanel{padding:20px;vertical-align:top}.wfu_pdusers_roles_container>label,.wfu_pdusers_users_container>label{font-weight:700}.wfu_pdusers_users_leftpanel label{display:block}.wfu_pdusers_users_midpanel label,.wfu_pdusers_users_rightpanel label{display:block;visibility:hidden}.wfu_pdusers_users_leftpanel input[type=text]{width:100%;display:block}.wfu_pdusers_roles_leftpanel select{height:100%!important;line-height:100%!important}.wfu_pdusers_roles_leftpanel select,.wfu_pdusers_users_leftpanel select{min-width:100px;min-height:100px}.wfu_pdusers_roles_show,.wfu_pdusers_users_show{overflow-x:visible;overflow-y:scroll;height:100%}.wfu_pdusers_roles_back,.wfu_pdusers_users_back{border:1px solid gray;position:absolute;left:10px;top:10px;bottom:10px;right:10px;pointer-events:none},.wfu_pdusers_roles_back.active{background-color:rgba(255,255,255,.7)}.wfu_pdusers_roles_role,.wfu_pdusers_users_user{border:1px solid gray;text-align:center;padding:2px 24px 2px 4px;border-radius:1em;cursor:default;background-color:rgba(0,0,0,.05);position:relative;display:inline-block;white-space:nowrap}.wfu_pdusers_roles_all{text-align:center;padding:2px 20px;font-weight:700}.wfu_pdusers_roles_role span,.wfu_pdusers_users_user span{width:14px;height:14px;position:absolute;display:inline-block;right:3px;top:0;bottom:0;margin:auto;border:1px solid #888;border-radius:1em}.wfu_pdusers_roles_role span:after,.wfu_pdusers_roles_role span:before,.wfu_pdusers_users_user span:after,.wfu_pdusers_users_user span:before{content:'';height:1px;margin-top:0;position:absolute;width:10px;top:50%;right:2px;background:#888}.wfu_pdusers_roles_role span:before,.wfu_pdusers_users_user span:before{transform:rotate(45deg)}.wfu_pdusers_roles_role span:after,.wfu_pdusers_users_user span:after{transform:rotate(-45deg)}.wfu_pdusers_roles_role span:hover,.wfu_pdusers_users_user span:hover{background-color:rgba(0,0,0,.1);border:1px solid #1ebcc5}.wfu_pdusers_roles_role span:hover:after,.wfu_pdusers_roles_role span:hover:before,.wfu_pdusers_users_user span:hover:after,.wfu_pdusers_users_user span:hover:before{background:#1ebcc5}.wfu_pdusers_roles_add,.wfu_pdusers_users_add{width:20px;height:18px;display:inline-block;border:1px solid #888;border-radius:4px}.wfu_pdusers_roles_add:after,.wfu_pdusers_users_add:after{border:solid #555;border-width:0 3px 3px 0;display:inline-block;padding:3px;vertical-align:middle;transform:rotate(-45deg);content:'';margin-left:4px;margin-top:-2px}.wfu_pdusers_roles_add:hover,.wfu_pdusers_users_add:hover{border:1px solid #444;background-color:rgba(0,0,0,.1)}.wfu_pd_user_box0{width:100%}.wfu_pd_user_select0,.wfu_pdusers_users_leftpanel select{width:100%;height:100px!important;line-height:100px!important;min-width:100px;min-height:100px}
1
+ div.wfu_shortcode_container{display:inline-block;position:relative;width:50%;padding:0;margin:0;background:0 0;border:none}textarea.wfu_shortcode{width:100%}div.wfu_container{margin-top:10px}div.wfu_help_container{display:inline-block;position:relative;top:4px;padding:0;margin:0;background:0 0;border:none}div.wfu_help_container img{visibility:hidden}table.wfu_main_table th:hover div.wfu_help_container img{visibility:visible}table.wfu_inner_table th:hover div.wfu_help_container img{visibility:visible}div.wfu_restore_container{display:inline-block;position:relative;top:4px;padding:0;margin:0;background:0 0;border:none}div.wfu_restore_container img{visibility:hidden}table.wfu_main_table th:hover div.wfu_restore_container img{visibility:visible}table.wfu_inner_table th:hover div.wfu_restore_container img{visibility:visible}div.wfu_td_div{display:block;position:relative;width:100%;height:100%;padding:0;margin:0;background:0 0;border:none}div.wfu_container input.wfu_long_text{width:100%}div.wfu_container input.wfu_short_text{width:60px}div.wfu_container input{width:200px}div.wfu_container input[type=checkbox]{width:auto}div.wfu_container textarea{width:100%}table.wfu_main_table{table-layout:fixed}table.wfu_main_table tr:nth-child(odd){background-color:#f4f4f4}table.wfu_main_table tr:nth-child(even){background-color:transparent}table.wfu_main_table table.wfu_inner_table tr{background-color:transparent}table.wfu_main_table th{width:17%}table.wfu_main_table td:nth-child(2){width:33%}table.wfu_main_table td:nth-child(3){width:50%}table.wfu_main_table table.wfu_inner_table th{width:34%}table.wfu_main_table table.wfu_inner_table td:nth-child(2){width:66%}table.wfu_main_table tr.wfu_subcategory{background-color:#ddd}table.wfu_main_table tr.wfu_subcategory>th{padding-top:0;padding-bottom:0}select.wfu_variable{padding-top:1px;padding-bottom:1px;margin:0;height:auto;min-height:auto;font-size:smaller;line-height:1.4;background-color:#ddd;border:1px solid #ccc;color:#333;-webkit-border-radius:5px;-moz-border-radius:5px;-khtml-border-radius:5px;border-radius:5px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}span.wfu_variable{padding:1px;margin:0;font-size:smaller;background-color:#ddd;border:1px solid #ccc;color:#333;-webkit-border-radius:5px;-moz-border-radius:5px;-khtml-border-radius:5px;border-radius:5px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}div.wfu_date_container{display:inline-block;position:relative;width:auto;height:100%;padding:0;margin:0;background:0 0;border:none}.wfu_datereset_button{position:absolute;right:4px;top:0;bottom:0;margin:auto 0;opacity:.5}.wfu_datereset_button:hover{opacity:1}span.wfu_ptext_span{display:inline-block;width:60px}select.wfu_select_folders{height:auto;min-width:75%}select.wfu_select_folders_empty{font-style:italic;color:silver}.ftpinfo_header{white-space:nowrap}.ftpinfo_text{width:calc(100% - 7ch - 6px)!important}@media screen and (max-width:782px){.ftpinfo_text{width:100%!important}}.ftpinfo_tool.hidden{display:none}.ftpinfo_btn{display:inline-block;width:7ch}.ftpinfo_label{font-weight:600;margin-right:10px;display:inline-block;width:10ch}.ftpinfo_value{vertical-align:middle}.ftpinfo_error{background-color:#fffacd!important;color:red!important}div.wfu_subfolders_inner_shadow{position:absolute;width:100%;height:100%;padding:0;margin:0;border:none;background-color:rgba(255,255,255,.8)}option.wfu_select_folders_option_default{color:#00f}div.wfu_subfolder_nav_container{width:40px;margin:0;padding:0;border:none;background:0 0;display:inline-block;vertical-align:top}table.wfu_subfolder_nav{table-layout:fixed;width:100%;margin:0;padding:0;border:none;background:0 0;border-spacing:1px}table.wfu_subfolder_nav tr{margin:0;padding:0;border:none;background:0 0}table.wfu_subfolder_nav td{margin:0;padding:0!important;border:none;background:0 0;font-size:small;line-height:1;text-align:center}table.wfu_subfolder_nav button.button{margin:0;padding:0;width:17px;font-size:smaller;height:18px;line-height:1;color:#000;font-weight:700}table.wfu_subfolder_nav button.button:disabled{color:silver}.button.wfu_subfolder_nav_pressed,.button.wfu_subfolder_nav_pressed:focus,.button.wfu_subfolder_nav_pressed:hover{background:#4169e1}div.wfu_subfolder_tools_container{width:75%;margin:0;padding:0;border:none;background:0 0}table.wfu_subfolder_tools{table-layout:fixed;width:100%;margin:0;padding:0;border:none;background:0 0}table.wfu_subfolder_tools tr{margin:0;padding:0;border:none;background:0 0}table.wfu_subfolder_tools td{margin:0;padding:0;border:none;background:0 0;font-size:smaller}table.wfu_subfolder_tools td div{margin:0;padding:0;border:none;background:0 0;position:relative}table.wfu_subfolder_tools label{display:block;padding:0;margin:0;line-height:1}table.wfu_subfolder_tools input{width:100%;padding:0;margin:0}table.wfu_subfolder_tools input:disabled{width:100%;padding:0;margin:0;color:silver}table.wfu_subfolder_tools button.button{margin:0;padding:1px 0 0 0;width:17px;font-size:smaller;height:17px;line-height:1;position:absolute;bottom:2px}table.wfu_subfolder_tools button.button:disabled{color:silver}table.wfu_subfolder_tools button.button:disabled img{opacity:.4}.wfu_subfolder_tools_disabled{color:silver}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container{position:absolute;width:150px;height:150px;margin:0;padding:0;z-index:100;border:1px solid silver;box-shadow:1px 1px 2px;background-color:#fff;font-size:inherit}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container table{table-layout:fixed;width:100%;height:100%;border:none;background:#eee;margin:0;padding:0;border-spacing:0;font-size:inherit}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container tr{border:none;background:0 0;margin:0;padding:0;font-size:inherit}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td{border:none;background:0 0;margin:0;padding:2px;line-height:0;overflow:hidden;font-size:inherit}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div{position:relative;border:none;background:0 0;margin:0;padding:0;width:100%;height:100%;display:inline-block;line-height:1}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div button.button{font-size:inherit;line-height:1;height:17px;padding:4px;position:relative;width:auto;margin:0;bottom:auto}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container select{width:100%;height:100%;top:0;bottom:0;position:absolute;margin:0}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container label{color:#222;font-weight:700;position:absolute;top:0;bottom:0;height:10px;margin:auto}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div button.button.wfu_folder_browser_cancel{width:17px;height:17px;position:absolute;right:0;top:0;margin:0;padding:0}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div div.wfu_folder_browser_loading_container{position:absolute;width:100%;height:100%;top:0;bottom:0;margin:0;padding:0;background-color:rgba(255,255,255,.9);text-align:center}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div div.wfu_folder_browser_loading_container label{position:relative;display:block}table.wfu_subfolder_tools td div.wfu_subfolders_browser_container td div div.wfu_folder_browser_loading_container img{position:relative}.button.wfu_folder_browser_cancel img{vertical-align:top;margin-top:2px}div.wfu_mchecklist_container{display:inline-block;border:1px solid #ddd;border-radius:4px;padding:4px}div.wfu_mchecklist_item{display:inline-block}div.wfu_mchecklist_item label{vertical-align:baseline;margin-left:4px;cursor:default}div.wfu_mchecklist_item input:disabled+label{color:gray}div.wfu_mchecklist_item div{margin-left:4px}div.wfu_mchecklist_item:hover img{visibility:visible}div.wfu_mchecklist_checkall{display:inline-block;vertical-align:top;margin:0 0 0 10px}div.wfu_bloglist_checkbtn,div.wfu_postlist_checkbtn,div.wfu_rolelist_checkbtn,div.wfu_userlist_checkbtn{display:inline-block;vertical-align:top;margin:0 0 0 10px}table.wfu_bloglist_container,table.wfu_postlist_container,table.wfu_rolelist_container,table.wfu_stringmatch_container,table.wfu_userlist_container{border:none;background:0 0;margin:0;padding:0;border-spacing:0}table.wfu_bloglist_container tr:nth-child(odd),table.wfu_postlist_container tr:nth-child(odd),table.wfu_rolelist_container tr:nth-child(odd),table.wfu_userlist_container tr:nth-child(odd){border:none;background:0 0;background-color:transparent;margin:0;padding:0}table.wfu_bloglist_container td,table.wfu_postlist_container td,table.wfu_rolelist_container td,table.wfu_stringmatch_container td,table.wfu_userlist_container td{width:1%;border:none;background:0 0;margin:0;padding:0;vertical-align:top}table.wfu_postlist_container td{padding-right:20px}table.wfu_postlist_container td:last-child{padding-right:0}div.wfu_postlist_header{padding:0 10px}div.wfu_postlist_selectall{float:right}div.wfu_shadow{position:absolute;width:100%;height:100%;left:0;top:0;margin:0;padding:0;background-color:#fff;z-index:10;-moz-opacity:.6;-khtml-opacity:.6;opacity:.6}table.wfu_main_table tr:nth-child(odd) div.wfu_shadow{background-color:#f4f4f4}div.wfu_onoff_container_off,div.wfu_onoff_container_on{display:inline-block;position:relative;padding:2px;border:1px solid #aaa;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px;background:#066dab;background:-moz-linear-gradient(top,#066dab 0,#c5deea 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#066dab),color-stop(100%,#c5deea));background:-webkit-linear-gradient(top,#066dab 0,#c5deea 100%);background:-o-linear-gradient(top,#066dab 0,#c5deea 100%);background:-ms-linear-gradient(top,#066dab 0,#c5deea 100%);background:linear-gradient(to bottom,#066dab 0,#c5deea 100%)}span.wfu_onoff_text{width:30px;display:inline-block;text-align:center;color:#fff}div.wfu_onoff_slider{position:absolute;margin:0;width:31px;top:0;bottom:0;border:1px solid #fff;-webkit-border-radius:2px;-moz-border-radius:2px;-khtml-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 2px;-webkit-box-shadow:0 0 2px;box-shadow:0 0 2px;background:#ccc;background:-moz-linear-gradient(top,#ccc 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#ccc),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ccc 0,#fff 100%);background:-o-linear-gradient(top,#ccc 0,#fff 100%);background:-ms-linear-gradient(top,#ccc 0,#fff 100%);background:linear-gradient(to bottom,#ccc 0,#fff 100%)}div.wfu_onoff_container_on div.wfu_onoff_slider{left:50%}div.wfu_onoff_container_off div.wfu_onoff_slider{left:0}@-webkit-keyframes set_on{from{left:0}to{left:50%}}@-moz-keyframes set_on{from{left:0}to{left:50%}}@-o-keyframes set_on{from{left:0}to{left:50%}}@keyframes set_on{from{left:0}to{left:50%}}div.wfu_placements_wrapper{display:block;position:relative;margin:0;padding:0;background:0 0;border:none}div.wfu_placements_container{display:inline-block;position:relative;width:100%;height:300px;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px;padding:0;overflow:scroll;font-size:0;line-height:0;white-space:nowrap}div.wfu_componentlist_container{display:inline-block;position:absolute;width:auto;height:auto;top:0;left:100%;background:0 0;border:none;margin:0 0 0 20px;padding:0;z-index:1;white-space:nowrap}div.wfu_component_box_container{display:inline-block;position:relative;width:80px;height:30px;background-color:transparent;border:1px solid transparent;padding:4px;margin:0;cursor:default}div.wfu_component_box_base{display:block;position:absolute;width:80px;height:30px;left:-1px;top:-1px;background-color:#ddd;border:1px solid #bbb;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px;padding:4px;cursor:default;font-size:12px;line-height:1;-moz-opacity:.4;-khtml-opacity:.4;opacity:.4;white-space:normal}div.wfu_component_box{display:inline-block;position:relative;width:80px;height:30px;background-color:#ddd;border:1px solid #bbb;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px;padding:4px;cursor:default;font-size:12px;line-height:1;z-index:1;white-space:normal}div.wfu_component_box_inner{display:table;width:100%;height:100%}div.wfu_component_box_label{display:table-cell;text-align:center;vertical-align:middle}div.wfu_component_box_index{background-color:coral;padding:1px;float:right;border-radius:10px}div.wfu_inbase{display:block;position:absolute;left:-1px;top:-1px}div.wfu_component_box:hover{background-color:#eee;border:1px solid #bbb}div.wfu_component_box_selected{background-color:#aaa;border:1px solid #bbb}div.wfu_component_box_dragged{-moz-opacity:.4;-khtml-opacity:.4;opacity:.4}div.wfu_component_separator_ver{display:inline-block;position:relative;width:8px;height:26px;background-color:transparent;border:1px solid transparent;margin:6px -8px;padding:0 8px;cursor:default;z-index:1}div.wfu_component_separator_hor{display:block;position:relative;width:100%;height:8px;background-color:transparent;border:1px solid transparent;margin:-8px 0;padding:8px 0;cursor:default;z-index:1}div.wfu_component_bar_hor{position:absolute;width:auto;height:4px;left:10px;right:0;background-color:silver;border:none;margin:11px 0 0 0;padding:0;display:none}div.wfu_component_bar_ver{position:absolute;width:4px;height:40px;background-color:silver;border:none;margin:-6px 0 0 11px;padding:0;display:none}div.wfu_componentlist_dragdrop{position:absolute;width:100%;height:100%;left:0;top:0;background-color:#f8f8f8;border:4px dashed #aaa;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;z-index:2;-moz-opacity:.7;-khtml-opacity:.7;opacity:.7}div.wfu_componentlist_dragdrop_dragover{border:4px dashed #555}div.wfu_formdata_container,div.wfu_userdata_container{display:block;position:relative;width:100%;height:100%;padding:0;margin:0;background:0 0;border:none}label.wfu_formdata_label{margin-right:6px}.wfu_formdata_props{padding-left:20px}div.wfu_formdata_action,div.wfu_userdata_action{display:inline-block;position:relative;top:2px;width:16px;height:16px;padding:0;margin:0;background:0 0;text-align:center;border:1px solid transparent;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}div.wfu_formdata_action:hover,div.wfu_userdata_action:hover{border:1px solid #aaa}div.wfu_formdata_action.wfu_formdata_action_disabled:hover,div.wfu_userdata_action.wfu_userdata_action_disabled:hover{border:1px solid transparent}div.wfu_formdata_action>img,div.wfu_userdata_action>img{width:12px;height:12px}div.wfu_formdata_action_disabled>img,div.wfu_userdata_action_disabled>img{-moz-opacity:.4;-khtml-opacity:.4;opacity:.4}div.wfu_formdata_line_container,div.wfu_userdata_line{display:block;position:relative;padding:0;margin:0;background:0 0;border:none;white-space:nowrap}table.wfu_formdata_props_table{background:0 0;border:none;padding:0}table.wfu_formdata_props_table td,table.wfu_main_table table.wfu_inner_table table.wfu_formdata_props_table td{background:0 0;border:none;padding:0;width:auto}table.wfu_formdata_props_table td.wfu_formdata_props,table.wfu_main_table table.wfu_inner_table table.wfu_formdata_props_table td.wfu_formdata_props{padding-left:20px}table.wfu_main_table td,table.wfu_main_table th{padding-top:15px}@media screen and (max-width:782px){.wfumain table.form-table td{width:100%!important}.wfumain .wp-list-table td[data-colname=Shortcode]{padding-left:8px!important}.wfumain .wp-list-table td[data-colname=Shortcode]:before{position:relative!important;margin-left:-8px!important;content:'Shortcode:'!important}div.wfu_shortcode_container{width:100%}table.wfu_main_table table.wfu_inner_table th,table.wfu_main_table th{width:50%}table.wfu_main_table table.wfu_inner_table td,table.wfu_main_table table.wfu_inner_table td:nth-child(2),table.wfu_main_table table.wfu_inner_table td:nth-child(3),table.wfu_main_table td,table.wfu_main_table td:nth-child(2),table.wfu_main_table td:nth-child(3){width:100%}#wpbody table.wfu_main_table select{height:auto!important}div.wfu_componentlist_container{position:relative;left:0}select.wfu_select_folders{width:calc(100% - 50px)!important;display:inline-block!important}table.wfu_formdata_props_table tbody tr:first-child td{display:table-cell}table.wfu_formdata_props_table tbody tr:first-child td:nth-child(2){padding-left:10px}.CodeMirror{width:100%!important}}div.wfu_color_container{display:block;position:relative;padding:0;margin:0;background:0 0;border:none;white-space:nowrap;z-index:1}input[type=text].wp-color-picker{width:75px}input[type=button].wp-picker-clear{width:62px}span.wfu_save_label{background-color:#f0f8ff;color:#32cd32;border-radius:6px;padding:1px 2px;box-shadow:1px 1px 1px;font-size:smaller;opacity:0}span.wfu_save_label_fail{background-color:beige;color:#f08080;border-radius:6px;padding:1px 2px;box-shadow:1px 1px 1px;font-size:smaller;opacity:0}div.wfu_global_dialog_container{position:fixed;width:100%;height:100%;top:0;left:0;margin:0;padding:0;border:none;background:0 0;z-index:1;display:none}table.wfu_main_table table.wfu_columns_container{border:none;background:0 0;margin:0;padding:0;border-spacing:0}table.wfu_main_table table.wfu_columns_container tr{background:0 0}table.wfu_main_table table.wfu_columns_container td{border:none;background:0 0;margin:0;padding:0;vertical-align:top;width:auto}table.wfu_main_table table.wfu_columnprops_container{border:none;background:0 0;margin:0;padding:6px;border-spacing:0;width:100%;box-shadow:0 0 1px #aaa}table.wfu_main_table table.wfu_columnprops_container tr{background:0 0}table.wfu_main_table table.wfu_columnprops_container td{border:none;background:0 0;margin:0;padding:0;vertical-align:middle;width:auto}table.wfu_main_table table.wfu_columnprops_container_disabled label{color:#ccc}table.wfu_main_table table.wfu_columnprops_container label.wfu_columnprops_label_disabled{color:#ccc}button.wfu_columns_addbutton{font-size:smaller}option.wfu_columns_item_required{color:gray}option.wfu_columns_item_defaultsort{text-decoration:underline}@font-face{font-family:wfu-icons;src:url(../images/fonts/wfu-icons.eot?xnqdfz);src:url(../images/fonts/wfu-icons.eot?xnqdfz#iefix) format('embedded-opentype'),url(../images/fonts/wfu-icons.ttf?xnqdfz) format('truetype'),url(../images/fonts/wfu-icons.woff?xnqdfz) format('woff'),url(../images/fonts/wfu-icons.svg?xnqdfz#wfu-icons) format('svg');font-weight:400;font-style:normal}.wfu-dashicons-media-external:before{font-family:wfu-icons;content:"\e900"}.wfu-dashicons-ftp:before{font-family:wfu-icons;content:"\e901"}.wfu-uploadedfiles .wfu-dashicons-after{margin-left:4px}.wfu-uploadedfiles .wfu-dashicons-hidden{display:none}.wfu-uploadedfiles .wfu-properties.wfu-clicked,.wfu-uploadedfiles .wfu-properties:hover{color:#00f}.wfu-uploadedfiles .wfu_unread{box-shadow:4px 0 0 inset #0f0;font-weight:700}.wfu-uploadedfiles .wfu-remarks-container:before{content:'-';width:0;display:inline-block;overflow:hidden}.wfu-adminbrowser .wfu-highlighted{box-shadow:0 -1000px 0 inset rgba(0,255,0,.2)}.wfu-historylog .wfu-highlighted{box-shadow:0 -1000px 0 inset rgba(0,255,0,.2)}.wfu_cleanlog_tr{display:none}.wfu_cleanlog_tr td{margin-top:0;padding-top:0}.wfu_selectdate_container,.wfu_selectdates_container,.wfu_selectperiod_container{display:none}.wfu_buttons_container,.wfu_includefiles_container,.wfu_selectdate_container,.wfu_selectdates_container,.wfu_selectperiod_container{margin-top:10px}.wfu_selectdate_container input[type=text],.wfu_selectdates_container input[type=text]{width:8em;text-align:center}.wfu_selectperiod_container input[type=number]{width:4em}.wfu_includefiles_container label{font-size:80%;opacity:.5}.wfu_includefiles_container input[type=checkbox]{transform:scale(.8,.8)}.wfu_buttons_container .button,.wfu_buttons_container .wfu_cleanlog_error,.wfu_includefiles_container input[type=checkbox],.wfu_includefiles_container label,.wfu_selectdate_container input[type=text],.wfu_selectdate_container label,.wfu_selectdates_container input[type=text],.wfu_selectdates_container label,.wfu_selectperiod_container input[type=number],.wfu_selectperiod_container label,.wfu_selectperiod_container select{vertical-align:middle}.wfu_cleanlog_proceed.disabled{pointer-events:none}.wfu_cleanlog_error{color:red;font-size:small}.wfu_cleanlog_error:before{content:'!';font-weight:700;margin-right:2px}.wfu_cleanlog_error.hidden{display:none}.wfu-filters{float:left}.subsubsub{margin:0;line-height:2}.subsubsub label.current{color:#000}.subsubsub label.current{font-weight:600;border:none}.subsubsub label{line-height:2;padding:.2em .2em .2em 0;text-decoration:none}.subsubsub input[type=checkbox]{margin:0 0 0 .2em}.wfu_conop_header,.wfu_pdop_header{transition:.4s;padding:6px}.wfu_conop_header label,.wfu_pdop_header label{font-weight:700;cursor:default}.wfu_conop_header.atomic label,.wfu_pdop_header.atomic label{font-weight:400}.wfu_consent_logactions,.wfu_consent_operations,.wfu_consent_permissions,.wfu_consent_questions,.wfu_consent_users,.wfu_plugin_operations{display:none}.wfu_pdheader_button{color:#777;padding:2px;border:1px solid gray;border-radius:1em;width:1em;height:1em;text-align:center;vertical-align:middle;position:relative;cursor:pointer;display:inline-block;font-size:smaller}.wfu_pdheader_button:after{content:'\02795';position:absolute;left:0;right:0;top:0;bottom:0;margin:auto}.wfu_pdheader_button.expanded:after{content:'\02796'}.wfu_conop_topmost_panel,.wfu_pdop_topmost_panel{margin-left:40px;overflow:hidden}.wfu_conop_panel,.wfu_pdop_panel{margin-left:40px;display:none;overflow:hidden}.wfu_conop_level_1,.wfu_pdop_level_1{padding:10px;font-size:larger}.wfu_conop_level_2,.wfu_pdop_level_2{padding:6px;font-size:smaller}.wfu_conop_level_3,.wfu_pdop_level_3{padding:2px}.wfu_conop_level_4,.wfu_pdop_level_4{padding:2px}.wfu_conop_level_5,.wfu_pdop_level_5{padding:2px}.wfu_conop_header:hover,.wfu_pdop_header:hover{background-color:rgba(0,0,0,.2)}input[type=checkbox].wfu_conop_selector,input[type=checkbox].wfu_pdop_selector{-webkit-appearance:checkbox}.wfu_conop_button,.wfu_pdop_button{color:#777;float:right;padding:2px;border:1px solid gray;border-radius:4px;width:1em;height:1em;text-align:center;position:relative;cursor:pointer;display:none}.wfu_conop_button:after,.wfu_pdop_button:after{content:'\02795';position:absolute;left:0;right:0;top:0;bottom:0;margin:auto;font-size:smaller}.wfu_conop_button.expanded:after,.wfu_pdop_button.expanded:after{content:'\02796'}.wfu_conop_header:hover .wfu_conop_button,.wfu_pdop_header:hover .wfu_pdop_button{display:block}input[type=checkbox].wfu_conop_selector,input[type=checkbox].wfu_pdop_selector{margin:0 0 0 4px}.wfu_conquestions_operations{margin-top:20px;margin-left:40px}.wfu_conquestions_operations label{display:block;font-size:larger;font-weight:700}.wfu_conquestions_oppanel{background-color:#fff;padding:10px;display:inline-block;margin-top:10px}.wfu_conquestions_optable{border-collapse:collapse}.wfu_conquestions_optable tbody tr:hover{background-color:rgba(0,0,0,.1)}.wfu_conquestions_optable td{cursor:default}.wfu_conquestions_optable td:not(:first-child){text-align:center}.wfu_op_unassigned{background-color:#ffdb99}.wfu_conquestions_optable tbody tr.wfu_op_unassigned:hover{background-color:#e6c58a}.wfu_op_unassigned .wfu_conquestions_opinv,.wfu_op_unassigned .wfu_conquestions_opsel{background-color:#ffdb99}.wfu_conquestions_optable tbody tr.wfu_op_unassigned:hover .wfu_conquestions_opinv,.wfu_conquestions_optable tbody tr.wfu_op_unassigned:hover .wfu_conquestions_opsel{background-color:#e6c58a}.wfu_conquestions_opsel.wfu_forced_selection{opacity:.5}.wfu_frozen{pointer-events:none}.wfu_conquestions_container{margin-top:20px;margin-left:40px}.wfu_conquestion_header{font-size:larger}.wfu_conquestion_subcontainer{padding:10px}.wfu_conquestion_headerlabel{font-weight:700}.wfu_conquestion_tools{float:right}.wfu_conquestion_itemprops,.wfu_conquestion_itemspreview,.wfu_conquestion_mainprops{display:table-cell;position:relative;border:1px solid silver;padding:4ex 10px 10px 10px;vertical-align:top;min-width:10em;min-height:4ex;resize:both;overflow:auto}.wfu_conquestion_itempropstitle,.wfu_conquestion_itemspreviewtitle,.wfu_conquestion_mainpropstitle{position:absolute;top:0;left:0;height:3ex;font-size:inherit;text-align:center;width:100%;background-color:rgba(0,0,0,.1)}.wfu_conquestion_displayedtitle,.wfu_conquestion_groupedlabel,.wfu_conquestion_labellabel,.wfu_conquestion_labellocationlabel,.wfu_conquestion_matrixlabel,.wfu_conquestion_preselectedlabel,.wfu_conquestion_titlelabel,.wfu_conquestion_titlelocationlabel,.wfu_conquestion_typelabel,.wfu_conquestion_visiblelabel{display:block}.wfu_conquestion_labeltext,.wfu_conquestion_titletext{width:100%}.wfu_conquestion_matrix_x,.wfu_conquestion_matrix_y{width:4em;text-align:center}.wfu_conquestion_matrixsep{width:1em;display:inline-block;text-align:center}.wfu_empty_label{font-style:italic}.wfu_conquestion_itemtable td:hover{background-color:rgba(0,0,0,.1)}.wfu_conquestion_itemcontainer{opacity:.5}.wfu_item_selected{background-color:rgba(0,0,0,.2)}.wfu_item_assigned{color:#00f}.wfu_item_visible{opacity:1}.wfu_conquestion_btn{display:inline-block;position:relative;width:16px;height:16px;padding:0;margin:0;background:0 0;text-align:center;border:1px solid transparent;-webkit-border-radius:3px;-moz-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}div.wfu_conquestion_btn:hover{border:1px solid #aaa}.wfu_conquestion_btn>img{width:12px;height:12px;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto}div.wfu_conquestion_btn.wfu_tool_disabled:hover{border:1px solid transparent}.wfu_conquestion_btn.wfu_tool_disabled>img{opacity:.4}.wfu_permissions_topmost_panel{margin-left:40px}.wfu_permissions_panel{background-color:#fff;padding:10px;display:inline-block;margin-top:20px}.wfu_perm_container{padding-right:20px}.wfu_location_cell{text-align:center}.wfu_perm_level_1{padding-left:0}.wfu_perm_level_2{padding-left:20px}.wfu_perm_level_3{padding-left:40px}.wfu_permissions_table{border-collapse:collapse}.wfu_permissions_table td:nth-child(n+2),.wfu_permissions_table tr:nth-child(2) th{border-left:1px solid rgba(0,0,0,.1)}.wfu_perm_row:hover{background-color:rgba(0,0,0,.1)}.wfu_perm_button{color:#777;border:1px solid gray;width:1.5ex;height:1.5ex;text-align:center;position:relative;cursor:pointer;display:inline-block;vertical-align:middle}.wfu_perm_button:after{content:'+';position:absolute;left:0;right:0;top:-.75ex;bottom:0;margin:auto}.wfu_perm_button:hover{color:#000}.wfu_perm_button.expanded:after{content:'-'}input[type=checkbox].wfu_location_selector{-webkit-appearance:checkbox;margin:0}.wfu_logactions_topmost_panel{margin-left:40px}.wfu_logactions_panel{background-color:#fff;padding:10px;display:inline-block;margin-top:20px}.wfu_log_container{padding-right:20px}.wfu_entity_cell{text-align:center}.wfu_log_level_1{padding-left:0}.wfu_log_level_2{padding-left:20px}.wfu_log_level_3{padding-left:40px}.wfu_logactions_table{border-collapse:collapse}.wfu_logactions_table td:nth-child(n+2),.wfu_logactions_table tr:nth-child(2) th{border-left:1px solid rgba(0,0,0,.1)}.wfu_log_row:hover{background-color:rgba(0,0,0,.1)}.wfu_log_button{color:#777;border:1px solid gray;width:1.5ex;height:1.5ex;text-align:center;position:relative;cursor:pointer;display:inline-block;vertical-align:middle}.wfu_log_button:after{content:'+';position:absolute;left:0;right:0;top:-.75ex;bottom:0;margin:auto}.wfu_log_button:hover{color:#000}.wfu_log_button.expanded:after{content:'-'}input[type=checkbox].wfu_entity_selector{-webkit-appearance:checkbox;margin:0}.wfu_pdusers_topmost_panel{margin-top:20px;margin-left:40px}.wfu_pdusers_topmost_panel>label{display:block;font-size:larger;font-weight:700}.wfu_pdusers_rolepanel,.wfu_pdusers_userpanel{margin-top:20px;margin-bottom:20px}.wfu_pdusers_roles_container,.wfu_pdusers_users_container{display:inline-block}.wfu_pdusers_roles_leftpanel,.wfu_pdusers_roles_midpanel,.wfu_pdusers_roles_rightpanel,.wfu_pdusers_users_leftpanel,.wfu_pdusers_users_midpanel,.wfu_pdusers_users_rightpanel{display:table-cell;position:relative}.wfu_pdusers_roles_leftpanel,.wfu_pdusers_roles_rightpanel{height:200px;min-width:100px}.wfu_pdusers_users_leftpanel,.wfu_pdusers_users_rightpanel{height:100px;min-width:100px}.wfu_pdusers_roles_leftpanel,.wfu_pdusers_users_leftpanel{padding:10px 10px 10px 0}.wfu_pdusers_roles_midpanel,.wfu_pdusers_users_midpanel{padding:10px 0;vertical-align:top}.wfu_pdusers_roles_rightpanel,.wfu_pdusers_users_rightpanel{padding:20px;vertical-align:top}.wfu_pdusers_roles_container>label,.wfu_pdusers_users_container>label{font-weight:700}.wfu_pdusers_users_leftpanel label{display:block}.wfu_pdusers_users_midpanel label,.wfu_pdusers_users_rightpanel label{display:block;visibility:hidden}.wfu_pdusers_users_leftpanel input[type=text]{width:100%;display:block}.wfu_pdusers_roles_leftpanel select{height:100%!important;line-height:100%!important}.wfu_pdusers_roles_leftpanel select,.wfu_pdusers_users_leftpanel select{min-width:100px;min-height:100px}.wfu_pdusers_roles_show,.wfu_pdusers_users_show{overflow-x:visible;overflow-y:scroll;height:100%}.wfu_pdusers_roles_back,.wfu_pdusers_users_back{border:1px solid gray;position:absolute;left:10px;top:10px;bottom:10px;right:10px;pointer-events:none},.wfu_pdusers_roles_back.active{background-color:rgba(255,255,255,.7)}.wfu_pdusers_roles_role,.wfu_pdusers_users_user{border:1px solid gray;text-align:center;padding:2px 24px 2px 4px;border-radius:1em;cursor:default;background-color:rgba(0,0,0,.05);position:relative;display:inline-block;white-space:nowrap}.wfu_pdusers_roles_all{text-align:center;padding:2px 20px;font-weight:700}.wfu_pdusers_roles_role span,.wfu_pdusers_users_user span{width:14px;height:14px;position:absolute;display:inline-block;right:3px;top:0;bottom:0;margin:auto;border:1px solid #888;border-radius:1em}.wfu_pdusers_roles_role span:after,.wfu_pdusers_roles_role span:before,.wfu_pdusers_users_user span:after,.wfu_pdusers_users_user span:before{content:'';height:1px;margin-top:0;position:absolute;width:10px;top:50%;right:2px;background:#888}.wfu_pdusers_roles_role span:before,.wfu_pdusers_users_user span:before{transform:rotate(45deg)}.wfu_pdusers_roles_role span:after,.wfu_pdusers_users_user span:after{transform:rotate(-45deg)}.wfu_pdusers_roles_role span:hover,.wfu_pdusers_users_user span:hover{background-color:rgba(0,0,0,.1);border:1px solid #1ebcc5}.wfu_pdusers_roles_role span:hover:after,.wfu_pdusers_roles_role span:hover:before,.wfu_pdusers_users_user span:hover:after,.wfu_pdusers_users_user span:hover:before{background:#1ebcc5}.wfu_pdusers_roles_add,.wfu_pdusers_users_add{width:20px;height:18px;display:inline-block;border:1px solid #888;border-radius:4px}.wfu_pdusers_roles_add:after,.wfu_pdusers_users_add:after{border:solid #555;border-width:0 3px 3px 0;display:inline-block;padding:3px;vertical-align:middle;transform:rotate(-45deg);content:'';margin-left:4px;margin-top:-2px}.wfu_pdusers_roles_add:hover,.wfu_pdusers_users_add:hover{border:1px solid #444;background-color:rgba(0,0,0,.1)}.wfu_pd_user_box0{width:100%}.wfu_pd_user_select0,.wfu_pdusers_users_leftpanel select{width:100%;height:100px!important;line-height:100px!important;min-width:100px;min-height:100px}
lib/wfu_admin_log.php CHANGED
@@ -1,204 +1,207 @@
1
- <?php
2
-
3
- /**
4
- * View Log Page in Dashboard Area of Plugin
5
- *
6
- * This file contains functions related to View Log page of plugin's Dashboard
7
- * area.
8
- *
9
- * @link /lib/wfu_admin_log.php
10
- *
11
- * @package WordPress File Upload Plugin
12
- * @subpackage Core Components
13
- * @since 2.4.1
14
- */
15
-
16
- /**
17
- * Display the View Log Page.
18
- *
19
- * This function displays the View Log page of the plugin's Dashboard area.
20
- *
21
- * @since 2.4.1
22
- *
23
- * @param integer $page Optional. The page to display in case log contents are
24
- * paginated.
25
- * @param bool $only_table_rows Optional. Return only the HTML code of the table
26
- * rows.
27
- * @param bool $located_rec Optional. The unique ID of a log record to focus and
28
- * highlight.
29
- *
30
- * @return string The HTML output of the plugin's View Log Dashboard page.
31
- */
32
- function wfu_view_log($page = 1, $only_table_rows = false, $located_rec = -1) {
33
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
34
- global $wpdb;
35
- $siteurl = site_url();
36
- $table_name1 = $wpdb->prefix . "wfu_log";
37
- $table_name2 = $wpdb->prefix . "wfu_userdata";
38
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
39
-
40
- if ( !current_user_can( 'manage_options' ) ) return;
41
-
42
- $maxrows = (int)WFU_VAR("WFU_HISTORYLOG_TABLE_MAXROWS");
43
- //get log data from database
44
- $files_total = $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1);
45
- //if we need to locate and focus on a specific record, then we need to
46
- //recalculate and define the right page
47
- if ( $located_rec > 0 && $maxrows > 0 ) {
48
- $files_before = $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1.' WHERE idlog > '.(int)$located_rec);
49
- $page = floor( $files_before / $maxrows ) + 1;
50
- }
51
- $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' ORDER BY date_from DESC'.( $maxrows > 0 ? ' LIMIT '.$maxrows.' OFFSET '.(($page - 1) * $maxrows) : '' ));
52
-
53
- $echo_str = "";
54
- if ( !$only_table_rows ) {
55
- $echo_str .= "\n".'<div class="wrap">';
56
- $echo_str .= "\n\t".'<h2>Wordpress File Upload Control Panel</h2>';
57
- $echo_str .= "\n\t".'<div style="margin-top:20px;">';
58
- $echo_str .= wfu_generate_dashboard_menu("\n\t\t", "View Log");
59
- $echo_str .= "\n\t".'<div style="position:relative;">';
60
- $echo_str .= wfu_add_loading_overlay("\n\t\t", "historylog");
61
- $echo_str .= "\n\t\t".'<div class="wfu_historylog_header" style="width: 100%;">';
62
- if ( $maxrows > 0 ) {
63
- $pages = max(ceil($files_total / $maxrows), 1);
64
- if ( $page > $pages ) $page = $pages;
65
- $echo_str .= wfu_add_pagination_header("\n\t\t\t", "historylog", $page, $pages);
66
- }
67
- $echo_str .= "\n\t\t".'</div>';
68
- $echo_str .= "\n\t\t".'<table id="wfu_historylog_table" class="wfu-historylog wp-list-table widefat fixed striped">';
69
- $echo_str .= "\n\t\t\t".'<thead>';
70
- $echo_str .= "\n\t\t\t\t".'<tr>';
71
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="5%" class="manage-column">';
72
- $echo_str .= "\n\t\t\t\t\t\t".'<label>#</label>';
73
- $echo_str .= "\n\t\t\t\t\t".'</th>';
74
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="30%" class="manage-column column-primary">';
75
- $echo_str .= "\n\t\t\t\t\t\t".'<label>File</label>';
76
- $echo_str .= "\n\t\t\t\t\t".'</th>';
77
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column">';
78
- $echo_str .= "\n\t\t\t\t\t\t".'<label>Action</label>';
79
- $echo_str .= "\n\t\t\t\t\t".'</th>';
80
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="15%" class="manage-column">';
81
- $echo_str .= "\n\t\t\t\t\t\t".'<label>Date</label>';
82
- $echo_str .= "\n\t\t\t\t\t".'</th>';
83
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="15%" class="manage-column">';
84
- $echo_str .= "\n\t\t\t\t\t\t".'<label>User</label>';
85
- $echo_str .= "\n\t\t\t\t\t".'</th>';
86
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="25%" class="manage-column">';
87
- $echo_str .= "\n\t\t\t\t\t\t".'<label>Remarks</label>';
88
- $echo_str .= "\n\t\t\t\t\t".'</th>';
89
- $echo_str .= "\n\t\t\t\t".'</tr>';
90
- $echo_str .= "\n\t\t\t".'</thead>';
91
- $echo_str .= "\n\t\t\t".'<tbody>';
92
- }
93
-
94
- $userdatarecs = $wpdb->get_results('SELECT * FROM '.$table_name2);
95
- $deletedfiles = array();
96
- $filecodes = array();
97
- $logpagecode = wfu_safe_store_browser_params('view_log&tag='.$page);
98
- $time0 = strtotime("0000-00-00 00:00:00");
99
- $i = ($page - 1) * $maxrows;
100
- $filerecs_count = count($filerecs);
101
- foreach ( $filerecs as $ind => $filerec ) {
102
- $remarks = '';
103
- if ( $filerec->action == 'delete' ) array_push($deletedfiles, $filerec->linkedto);
104
- elseif ( $filerec->action == 'rename' || $filerec->action == 'move' ) {
105
- $prevfilepath = '';
106
- $prevfilerec = wfu_get_file_rec_from_id($filerec->linkedto);
107
- if ( $prevfilerec != null ) $prevfilepath = $prevfilerec->filepath;
108
- if ( $prevfilepath != '' )
109
- $remarks = "\n\t\t\t\t\t\t".'<label>Previous filepath: '.$prevfilepath.'</label>';
110
- }
111
- elseif ( $filerec->action == 'upload' || $filerec->action == 'modify' || $filerec->action == 'datasubmit' ) {
112
- foreach ( $userdatarecs as $userdata ) {
113
- if ( $userdata->uploadid == $filerec->uploadid ) {
114
- $userdata_datefrom = strtotime($userdata->date_from);
115
- $userdata_dateto = strtotime($userdata->date_to);
116
- $filerec_datefrom = strtotime($filerec->date_from);
117
- if ( $filerec_datefrom >= $userdata_datefrom && ( $userdata_dateto == $time0 || $filerec_datefrom < $userdata_dateto ) )
118
- $remarks .= "\n\t\t\t\t\t\t\t".'<option>'.$userdata->property.': '.$userdata->propvalue.'</option>';
119
- }
120
- }
121
- if ( $remarks != '' ) {
122
- $remarks = "\n\t\t\t\t\t\t".'<select multiple="multiple" style="width:100%; height:40px; background:none; font-size:small; overflow:scroll; resize:vertical;">'.$remarks;
123
- $remarks .= "\n\t\t\t\t\t\t".'</select>';
124
- }
125
- }
126
- elseif ( $filerec->action == 'changeuser' ) {
127
- $prevuploaduserid = '';
128
- $prevfilerec = wfu_get_file_rec_from_id($filerec->linkedto);
129
- if ( $prevfilerec != null ) $prevuploaduserid = $prevfilerec->uploaduserid;
130
- if ( $prevuploaduserid != '' ) {
131
- $prevuploaduser = wfu_get_username_by_id($prevuploaduserid);
132
- $remarks = "\n\t\t\t\t\t\t".'<label>Previous upload user: '.$prevuploaduser.'</label>';
133
- }
134
- }
135
- elseif ( $filerec->action == 'other' ) {
136
- $info = $filerec->filepath;
137
- $filerec->filepath = '';
138
- $remarks = "\n\t\t\t\t\t\t".'<textarea style="width:100%; resize:vertical; background:none;" readonly="readonly">'.$info.'</textarea>';
139
- }
140
- $displayed_path = wfu_hide_credentials_from_ftpurl($filerec->filepath);
141
- $i ++;
142
- $echo_str .= "\n\t\t\t\t".'<tr'.( $located_rec > 0 && $filerec->idlog == $located_rec ? ' class="wfu-highlighted"' : '' ).'>';
143
- $echo_str .= "\n\t\t\t\t\t".'<th style="word-wrap: break-word;">'.$i.'</th>';
144
- $echo_str .= "\n\t\t\t\t\t".'<td class="column-primary" data-colname="File">';
145
- if ( $filerec->action == 'other' ) $echo_str .= "\n\t\t\t\t\t\t".'<span>Other action not related to file</span>';
146
- elseif ( $filerec->action == 'datasubmit' ) $echo_str .= "\n\t\t\t\t\t\t".'<span>Submission of data without file</span>';
147
- elseif ( in_array($filerec->linkedto, $deletedfiles) || in_array($filerec->idlog, $deletedfiles) ) $echo_str .= "\n\t\t\t\t\t\t".'<span>'.$displayed_path.'</span>';
148
- else {
149
- //find newest linked record
150
- $newestidlog = $filerec->idlog;
151
- $newestind = $ind;
152
- $parind = $ind;
153
- while ( $parind >= 0 && $filerecs[$newestind]->date_to != "0000-00-00 00:00:00" ) {
154
- if ( isset($filerecs[$parind]->linkedto) && $filerecs[$parind]->linkedto == $newestidlog ) {
155
- $newestind = $parind;
156
- $newestidlog = $filerecs[$parind]->idlog;
157
- }
158
- $parind --;
159
- }
160
- //find oldest linked record
161
- $oldestidlog = $filerec->idlog;
162
- $oldestind = $ind;
163
- $parind = $ind;
164
- while ( $parind < $filerecs_count && isset($filerecs[$oldestind]->linkedto) ) {
165
- if ( $filerecs[$parind]->idlog == $filerecs[$oldestind]->linkedto ) {
166
- $oldestind = $parind;
167
- $oldestidlog = $filerecs[$parind]->idlog;
168
- }
169
- $parind ++;
170
- }
171
- $lid = $oldestidlog;
172
- //make the file linkable only if the record is still valid, the
173
- //filename has not changed (due to a rename action) and the file
174
- //exists
175
- if ( $filerecs[$newestind]->date_to == "0000-00-00 00:00:00" && $filerec->filepath == $filerecs[$newestind]->filepath && wfu_file_exists(wfu_path_rel2abs($filerec->filepath), "wfu_view_log") ) {
176
- if ( !isset($filecodes[$lid]) ) $filecodes[$lid] = wfu_safe_store_filepath($filerec->filepath);
177
- $echo_str .= "\n\t\t\t\t\t\t".'<a class="row-title" href="'.$siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=file_details&file='.$filecodes[$lid].'&invoker='.$logpagecode.'" title="View and edit file details" style="font-weight:normal;">'.$displayed_path.'</a>';
178
- }
179
- else $echo_str .= "\n\t\t\t\t\t\t".'<span>'.$displayed_path.'</span>';
180
- }
181
- $echo_str .= "\n\t\t\t\t\t\t".'<button type="button" class="toggle-row"><span class="screen-reader-text">Show more details</span></button>';
182
- $echo_str .= "\n\t\t\t\t\t".'</td>';
183
- $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Action">'.( $filerec->action != 'other' && $filerec->action != 'datasubmit' ? $filerec->action : '' ).'</td>';
184
- $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Date">'.get_date_from_gmt($filerec->date_from).'</td>';
185
- $echo_str .= "\n\t\t\t\t\t".'<td data-colname="User">'.wfu_get_username_by_id($filerec->userid).'</td>';
186
- $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Remarks">';
187
- $echo_str .= $remarks;
188
- $echo_str .= "\n\t\t\t\t\t".'</td>';
189
- $echo_str .= "\n\t\t\t\t".'</tr>';
190
- }
191
- if ( !$only_table_rows ) {
192
- $echo_str .= "\n\t\t\t".'</tbody>';
193
- $echo_str .= "\n\t\t".'</table>';
194
- $echo_str .= "\n\t".'</div>';
195
- $echo_str .= "\n\t".'</div>';
196
- $echo_str .= "\n".'</div>';
197
- }
198
- if ( $located_rec > 0 ) {
199
- $handler = 'function() { wfu_focus_table_on_highlighted_file("wfu_historylog_table"); }';
200
- $echo_str .= "\n\t".'<script type="text/javascript">if(window.addEventListener) { window.addEventListener("load", '.$handler.', false); } else if(window.attachEvent) { window.attachEvent("onload", '.$handler.'); } else { window["onload"] = '.$handler.'; }</script>';
201
- }
202
-
203
- return $echo_str;
 
 
 
204
  }
1
+ <?php
2
+
3
+ /**
4
+ * View Log Page in Dashboard Area of Plugin
5
+ *
6
+ * This file contains functions related to View Log page of plugin's Dashboard
7
+ * area.
8
+ *
9
+ * @link /lib/wfu_admin_log.php
10
+ *
11
+ * @package WordPress File Upload Plugin
12
+ * @subpackage Core Components
13
+ * @since 2.4.1
14
+ */
15
+
16
+ /**
17
+ * Display the View Log Page.
18
+ *
19
+ * This function displays the View Log page of the plugin's Dashboard area.
20
+ *
21
+ * @since 2.4.1
22
+ *
23
+ * @param integer $page Optional. The page to display in case log contents are
24
+ * paginated.
25
+ * @param bool $only_table_rows Optional. Return only the HTML code of the table
26
+ * rows.
27
+ * @param bool $located_rec Optional. The unique ID of a log record to focus and
28
+ * highlight.
29
+ *
30
+ * @return string The HTML output of the plugin's View Log Dashboard page.
31
+ */
32
+ function wfu_view_log($page = 1, $only_table_rows = false, $located_rec = -1) {
33
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
34
+ global $wpdb;
35
+ $siteurl = site_url();
36
+ $table_name1 = $wpdb->prefix . "wfu_log";
37
+ $table_name2 = $wpdb->prefix . "wfu_userdata";
38
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
39
+
40
+ if ( !current_user_can( 'manage_options' ) ) return;
41
+
42
+ $maxrows = (int)WFU_VAR("WFU_HISTORYLOG_TABLE_MAXROWS");
43
+ //get log data from database
44
+ $files_total = $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1);
45
+ //if we need to locate and focus on a specific record, then we need to
46
+ //recalculate and define the right page
47
+ if ( $located_rec > 0 && $maxrows > 0 ) {
48
+ $files_before = $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1.' WHERE idlog > '.(int)$located_rec);
49
+ $page = floor( $files_before / $maxrows ) + 1;
50
+ }
51
+ $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' ORDER BY date_from DESC'.( $maxrows > 0 ? ' LIMIT '.$maxrows.' OFFSET '.(($page - 1) * $maxrows) : '' ));
52
+
53
+ $echo_str = "";
54
+ if ( !$only_table_rows ) {
55
+ $echo_str .= "\n".'<div class="wrap">';
56
+ $echo_str .= "\n\t".'<h2>Wordpress File Upload Control Panel</h2>';
57
+ $echo_str .= "\n\t".'<div style="margin-top:20px;">';
58
+ $echo_str .= wfu_generate_dashboard_menu("\n\t\t", "View Log");
59
+ $echo_str .= "\n\t".'<div style="position:relative;">';
60
+ $echo_str .= wfu_add_loading_overlay("\n\t\t", "historylog");
61
+ $echo_str .= "\n\t\t".'<div class="wfu_historylog_header" style="width: 100%;">';
62
+ if ( $maxrows > 0 ) {
63
+ $pages = max(ceil($files_total / $maxrows), 1);
64
+ if ( $page > $pages ) $page = $pages;
65
+ $echo_str .= wfu_add_pagination_header("\n\t\t\t", "historylog", $page, $pages);
66
+ }
67
+ $echo_str .= "\n\t\t".'</div>';
68
+ $echo_str .= "\n\t\t".'<table id="wfu_historylog_table" class="wfu-historylog wp-list-table widefat fixed striped">';
69
+ $echo_str .= "\n\t\t\t".'<thead>';
70
+ $echo_str .= "\n\t\t\t\t".'<tr>';
71
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="5%" class="manage-column">';
72
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>#</label>';
73
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
74
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="30%" class="manage-column column-primary">';
75
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>File</label>';
76
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
77
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column">';
78
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>Action</label>';
79
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
80
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="15%" class="manage-column">';
81
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>Date</label>';
82
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
83
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="15%" class="manage-column">';
84
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>User</label>';
85
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
86
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="25%" class="manage-column">';
87
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>Remarks</label>';
88
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
89
+ $echo_str .= "\n\t\t\t\t".'</tr>';
90
+ $echo_str .= "\n\t\t\t".'</thead>';
91
+ $echo_str .= "\n\t\t\t".'<tbody>';
92
+ }
93
+
94
+ $userdatarecs = $wpdb->get_results('SELECT * FROM '.$table_name2);
95
+ $deletedfiles = array();
96
+ $filecodes = array();
97
+ $logpagecode = wfu_safe_store_browser_params('view_log&tag='.$page);
98
+ $time0 = strtotime("0000-00-00 00:00:00");
99
+ $i = ($page - 1) * $maxrows;
100
+ $filerecs_count = count($filerecs);
101
+ foreach ( $filerecs as $ind => $filerec ) {
102
+ $remarks = '';
103
+ if ( $filerec->action == 'delete' ) array_push($deletedfiles, $filerec->linkedto);
104
+ elseif ( $filerec->action == 'rename' || $filerec->action == 'move' ) {
105
+ $prevfilepath = '';
106
+ $prevfilerec = wfu_get_file_rec_from_id($filerec->linkedto);
107
+ if ( $prevfilerec != null ) $prevfilepath = $prevfilerec->filepath;
108
+ if ( $prevfilepath != '' )
109
+ $remarks = "\n\t\t\t\t\t\t".'<label>Previous filepath: '.$prevfilepath.'</label>';
110
+ }
111
+ elseif ( $filerec->action == 'upload' || $filerec->action == 'modify' || $filerec->action == 'datasubmit' ) {
112
+ foreach ( $userdatarecs as $userdata ) {
113
+ if ( $userdata->uploadid == $filerec->uploadid ) {
114
+ $userdata_datefrom = strtotime($userdata->date_from);
115
+ $userdata_dateto = strtotime($userdata->date_to);
116
+ $filerec_datefrom = strtotime($filerec->date_from);
117
+ if ( $filerec_datefrom >= $userdata_datefrom && ( $userdata_dateto == $time0 || $filerec_datefrom < $userdata_dateto ) )
118
+ $remarks .= "\n\t\t\t\t\t\t\t".'<option>'.$userdata->property.': '.$userdata->propvalue.'</option>';
119
+ }
120
+ }
121
+ if ( $remarks != '' ) {
122
+ $remarks = "\n\t\t\t\t\t\t".'<select multiple="multiple" style="width:100%; height:40px; background:none; font-size:small; overflow:scroll; resize:vertical;">'.$remarks;
123
+ $remarks .= "\n\t\t\t\t\t\t".'</select>';
124
+ }
125
+ }
126
+ elseif ( $filerec->action == 'changeuser' ) {
127
+ $prevuploaduserid = '';
128
+ $prevfilerec = wfu_get_file_rec_from_id($filerec->linkedto);
129
+ if ( $prevfilerec != null ) $prevuploaduserid = $prevfilerec->uploaduserid;
130
+ if ( $prevuploaduserid != '' ) {
131
+ $prevuploaduser = wfu_get_username_by_id($prevuploaduserid);
132
+ $remarks = "\n\t\t\t\t\t\t".'<label>Previous upload user: '.$prevuploaduser.'</label>';
133
+ }
134
+ }
135
+ elseif ( $filerec->action == 'other' ) {
136
+ $info = $filerec->filepath;
137
+ $filerec->filepath = '';
138
+ $remarks = "\n\t\t\t\t\t\t".'<textarea style="width:100%; resize:vertical; background:none;" readonly="readonly">'.$info.'</textarea>';
139
+ }
140
+ $displayed_path = wfu_hide_credentials_from_ftpurl($filerec->filepath);
141
+ $i ++;
142
+ $echo_str .= "\n\t\t\t\t".'<tr'.( $located_rec > 0 && $filerec->idlog == $located_rec ? ' class="wfu-highlighted"' : '' ).'>';
143
+ $echo_str .= "\n\t\t\t\t\t".'<th style="word-wrap: break-word;">'.$i.'</th>';
144
+ $echo_str .= "\n\t\t\t\t\t".'<td class="column-primary" data-colname="File">';
145
+ if ( $filerec->action == 'other' ) $echo_str .= "\n\t\t\t\t\t\t".'<span>Other action not related to file</span>';
146
+ elseif ( $filerec->action == 'datasubmit' ) $echo_str .= "\n\t\t\t\t\t\t".'<span>Submission of data without file</span>';
147
+ elseif ( in_array($filerec->linkedto, $deletedfiles) || in_array($filerec->idlog, $deletedfiles) ) $echo_str .= "\n\t\t\t\t\t\t".'<span>'.$displayed_path.'</span>';
148
+ else {
149
+ //find newest linked record
150
+ $newestidlog = $filerec->idlog;
151
+ $newestind = $ind;
152
+ $parind = $ind;
153
+ while ( $parind >= 0 && $filerecs[$newestind]->date_to != "0000-00-00 00:00:00" ) {
154
+ if ( isset($filerecs[$parind]->linkedto) && $filerecs[$parind]->linkedto == $newestidlog ) {
155
+ $newestind = $parind;
156
+ $newestidlog = $filerecs[$parind]->idlog;
157
+ }
158
+ $parind --;
159
+ }
160
+ //find oldest linked record
161
+ $oldestidlog = $filerec->idlog;
162
+ $oldestind = $ind;
163
+ $parind = $ind;
164
+ while ( $parind < $filerecs_count && isset($filerecs[$oldestind]->linkedto) ) {
165
+ if ( $filerecs[$parind]->idlog == $filerecs[$oldestind]->linkedto ) {
166
+ $oldestind = $parind;
167
+ $oldestidlog = $filerecs[$parind]->idlog;
168
+ }
169
+ $parind ++;
170
+ }
171
+ $lid = $oldestidlog;
172
+ //make the file linkable only if the record is still valid, the
173
+ //filename has not changed (due to a rename action) and the file
174
+ //exists
175
+ $file_abspath = wfu_path_rel2abs($filerec->filepath);
176
+ if ( $filerecs[$newestind]->date_to == "0000-00-00 00:00:00" && $filerec->filepath == $filerecs[$newestind]->filepath && wfu_file_exists($file_abspath, "wfu_view_log") ) {
177
+ if ( !isset($filecodes[$lid]) ) {
178
+ $filecodes[$lid] = ( wfu_check_file_remote_basic($file_abspath) ? "byID:".$filerec->idlog : wfu_safe_store_filepath($filerec->filepath) );
179
+ }
180
+ $echo_str .= "\n\t\t\t\t\t\t".'<a class="row-title" href="'.$siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=file_details&file='.$filecodes[$lid].'&invoker='.$logpagecode.'" title="View and edit file details" style="font-weight:normal;">'.$displayed_path.'</a>';
181
+ }
182
+ else $echo_str .= "\n\t\t\t\t\t\t".'<span>'.$displayed_path.'</span>';
183
+ }
184
+ $echo_str .= "\n\t\t\t\t\t\t".'<button type="button" class="toggle-row"><span class="screen-reader-text">Show more details</span></button>';
185
+ $echo_str .= "\n\t\t\t\t\t".'</td>';
186
+ $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Action">'.( $filerec->action != 'other' && $filerec->action != 'datasubmit' ? $filerec->action : '' ).'</td>';
187
+ $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Date">'.get_date_from_gmt($filerec->date_from).'</td>';
188
+ $echo_str .= "\n\t\t\t\t\t".'<td data-colname="User">'.wfu_get_username_by_id($filerec->userid).'</td>';
189
+ $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Remarks">';
190
+ $echo_str .= $remarks;
191
+ $echo_str .= "\n\t\t\t\t\t".'</td>';
192
+ $echo_str .= "\n\t\t\t\t".'</tr>';
193
+ }
194
+ if ( !$only_table_rows ) {
195
+ $echo_str .= "\n\t\t\t".'</tbody>';
196
+ $echo_str .= "\n\t\t".'</table>';
197
+ $echo_str .= "\n\t".'</div>';
198
+ $echo_str .= "\n\t".'</div>';
199
+ $echo_str .= "\n".'</div>';
200
+ }
201
+ if ( $located_rec > 0 ) {
202
+ $handler = 'function() { wfu_focus_table_on_highlighted_file("wfu_historylog_table"); }';
203
+ $echo_str .= "\n\t".'<script type="text/javascript">if(window.addEventListener) { window.addEventListener("load", '.$handler.', false); } else if(window.attachEvent) { window.attachEvent("onload", '.$handler.'); } else { window["onload"] = '.$handler.'; }</script>';
204
+ }
205
+
206
+ return $echo_str;
207
  }
lib/wfu_admin_uploadedfiles.php CHANGED
@@ -1,676 +1,675 @@
1
- <?php
2
-
3
- /**
4
- * Uploaded Files Page in Dashboard Area of Plugin
5
- *
6
- * This file contains functions related to Uploaded Files page of plugin's
7
- * Dashboard area.
8
- *
9
- * @link /lib/wfu_admin_uploadedfiles.php
10
- *
11
- * @package WordPress File Upload Plugin
12
- * @subpackage Core Components
13
- * @since 4.7.0
14
- */
15
-
16
- /**
17
- * Process Dashboard Requests for Uploaded Files Page
18
- *
19
- * This function processes Dashboard requests and shows main Uploaded Files page
20
- * of the plugin.
21
- *
22
- * @since 4.7.0
23
- */
24
- function wfu_uploadedfiles_menu() {
25
- $_GET = stripslashes_deep($_GET);
26
- $tag = (!empty($_GET['tag']) ? $_GET['tag'] : '1');
27
- $page = max((int)$tag, 1);
28
- echo wfu_uploadedfiles_manager($page);
29
- }
30
-
31
- /**
32
- * Display the Uploaded Files Page.
33
- *
34
- * This function displays the Uploaded Files page of the plugin.
35
- *
36
- * @since 4.7.0
37
- *
38
- * @param integer $page Optional. The page to display in case contents are
39
- * paginated.
40
- * @param bool $only_table_rows Optional. Return only the HTML code of the table
41
- * rows.
42
- *
43
- * @return string The HTML output of the plugin's Uploaded Files Dashboard page.
44
- */
45
- function wfu_uploadedfiles_manager($page = 1, $only_table_rows = false) {
46
- global $wpdb;
47
- $table_name1 = $wpdb->prefix . "wfu_log";
48
- $table_name3 = $wpdb->prefix . "wfu_dbxqueue";
49
- $def_other_cols = array( 'upload_date', 'user', 'properties', 'remarks', 'actions' );
50
-
51
- if ( !current_user_can( 'manage_options' ) ) return;
52
-
53
- $siteurl = site_url();
54
- $maxrows = (int)WFU_VAR("WFU_UPLOADEDFILES_TABLE_MAXROWS");
55
-
56
- //get log data from database
57
- //$files_total = $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1.' WHERE action = \'upload\'');
58
- //$filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action = \'upload\' ORDER BY date_from DESC'.( $maxrows > 0 ? ' LIMIT '.$maxrows.' OFFSET '.(($page - 1) * $maxrows) : '' ));
59
- $files_total = 0;
60
- $filerecs = array();
61
- $has_history = false;
62
- extract(wfu_uploadedfiles_get_filerecs($page));
63
-
64
- //get last record already read
65
- $last_idlog = get_option( "wordpress_file_upload_last_idlog", array( "pre" => 0, "post" => 0, "time" => 0 ) );
66
-
67
- //get visible columns and their order
68
- $cols = array();
69
- $cols_raw = explode(',', WFU_VAR("WFU_UPLOADEDFILES_COLUMNS"));
70
- //normalize column list
71
- foreach ( $cols_raw as $ind => $col ) $cols_raw[$ind] = strtolower(trim($col));
72
- //check if '#' column is visible
73
- $id_visible = in_array('#', $cols_raw);
74
- //'file' column is always visible and follows '#' column
75
- //create an associative array $cols where keys are the columns and values
76
- //are either true for visible columns or false for hidden ones
77
- $visible_cols_count = 0;
78
- foreach ( $cols_raw as $col )
79
- if ( ($key = array_search($col, $def_other_cols)) !== false ) {
80
- unset($def_other_cols[$key]);
81
- $cols[$col] = true;
82
- $visible_cols_count ++;
83
- }
84
- foreach ( $def_other_cols as $col ) $cols[$col] = false;
85
-
86
- //prepare html
87
- $echo_str = "";
88
- if ( !$only_table_rows ) {
89
- //Update last_idlog option so that next time Uploaded Files menu item is
90
- //pressed files have been read.
91
- //Option last_idlog requires a minimum interval of some seconds, defined
92
- //by advanced variable WFU_UPLOADEDFILES_RESET_TIME, before it can be
93
- //updated. This way, if the admin presses Uploaded Files menu item two
94
- //times immediately, the same number of unread files will not change.
95
- //It is noted that last_idlog option uses two values, 'pre' and 'post'.
96
- //The way they are updated makes sure that the number of unread files
97
- //gets reset only when Uploaded Files menu item is pressed and not
98
- //when the admin browses through the pages of the list (when pagination
99
- //is activated).
100
- $limit = (int)WFU_VAR("WFU_UPLOADEDFILES_RESET_TIME");
101
- if ( $limit == -1 || time() > $last_idlog["time"] + $limit ) {
102
- $last_idlog["pre"] = $last_idlog["post"];
103
- $last_idlog["post"] = $wpdb->get_var('SELECT MAX(idlog) FROM '.$table_name1);
104
- $last_idlog["time"] = time();
105
- update_option( "wordpress_file_upload_last_idlog", $last_idlog );
106
- }
107
-
108
- $echo_str .= "\n".'<div class="wrap">';
109
- $echo_str .= "\n\t".'<h2>List of Uploaded Files</h2>';
110
- $echo_str .= "\n\t".'<div style="position:relative;">';
111
- $echo_str .= wfu_add_loading_overlay("\n\t\t", "uploadedfiles");
112
- $echo_str .= "\n\t\t".'<div class="wfu_uploadedfiles_header" style="width: 100%;">';
113
- if ( $maxrows > 0 ) {
114
- $pages = ceil($files_total / $maxrows);
115
- $echo_str .= wfu_add_pagination_header("\n\t\t\t", "uploadedfiles", $page, $pages);
116
- }
117
- $echo_str .= "\n\t\t\t".'<input id="wfu_download_file_nonce" type="hidden" value="'.wp_create_nonce('wfu_download_file_invoker').'" />';
118
- $echo_str .= "\n\t\t".'</div>';
119
- $echo_str .= "\n\t\t".'<table id="wfu_uploadedfiles_table" class="wfu-uploadedfiles wp-list-table widefat fixed striped">';
120
- $echo_str .= "\n\t\t\t".'<thead>';
121
- $echo_str .= "\n\t\t\t\t".'<tr>';
122
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="5%" class="manage-column'.( $id_visible ? '' : ' hidden' ).'">';
123
- $echo_str .= "\n\t\t\t\t\t\t".'<label>#</label>';
124
- $echo_str .= "\n\t\t\t\t\t".'</th>';
125
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="30%" class="manage-column column-primary">';
126
- $echo_str .= "\n\t\t\t\t\t\t".'<label>File</label>';
127
- $echo_str .= "\n\t\t\t\t\t".'</th>';
128
- foreach ( $cols as $col => $is_visible ) {
129
- if ( $col == 'upload_date' ) {
130
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
131
- $echo_str .= "\n\t\t\t\t\t\t".'<label>Upload Date</label>';
132
- $echo_str .= "\n\t\t\t\t\t".'</th>';
133
- }
134
- elseif ( $col == 'user' ) {
135
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
136
- $echo_str .= "\n\t\t\t\t\t\t".'<label>User</label>';
137
- $echo_str .= "\n\t\t\t\t\t".'</th>';
138
- }
139
- elseif ( $col == 'properties' ) {
140
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
141
- $echo_str .= "\n\t\t\t\t\t\t".'<label>Properties</label>';
142
- $echo_str .= "\n\t\t\t\t\t".'</th>';
143
- }
144
- elseif ( $col == 'remarks' ) {
145
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="25%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
146
- $echo_str .= "\n\t\t\t\t\t\t".'<label>Remarks</label>';
147
- $echo_str .= "\n\t\t\t\t\t".'</th>';
148
- }
149
- elseif ( $col == 'actions' ) {
150
- $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
151
- $echo_str .= "\n\t\t\t\t\t\t".'<label>Actions</label>';
152
- $echo_str .= "\n\t\t\t\t\t".'</th>';
153
- }
154
- }
155
- $echo_str .= "\n\t\t\t\t".'</tr>';
156
- $echo_str .= "\n\t\t\t".'</thead>';
157
- $echo_str .= "\n\t\t\t".'<tbody>';
158
- }
159
- //echo the number of unread uploaded files in order to update the
160
- //notification bubble of the toplevel menu item
161
- $unread_files_count = wfu_get_new_files_count($last_idlog["pre"]);
162
- $echo_str .= "\n\t\t\t".'<!-- wfu_uploadedfiles_unread['.$unread_files_count.'] -->';
163
-
164
- $i = ($page - 1) * $maxrows;
165
- $abspath_notrailing_slash = substr(wfu_abspath(), 0, -1);
166
- $pagecode = wfu_safe_store_browser_params('wfu_uploaded_files&tag='.$page);
167
- $nopagecode = wfu_safe_store_browser_params('no_referer');
168
- foreach ( $filerecs as $filerec ) {
169
- $i ++;
170
- $initialrec = $filerec;
171
- //get all newer associated file records
172
- $historyrecs = array();
173
- if ( $has_history ) $historyrecs = $filerec->history;
174
- else $historyrecs = wfu_get_rec_new_history($initialrec->idlog);
175
- //get the latest record of this upload
176
- $filerec = $historyrecs[count($historyrecs) - 1];
177
- $filedata = wfu_get_filedata_from_rec($filerec, false, true, false);
178
- if ( $filedata == null ) $filedata = array();
179
-
180
- $echo_str .= "\n\t\t\t\t".'<tr class="wfu_row-'.$i.( $initialrec->idlog > $last_idlog["pre"] ? ' wfu_unread' : '' ).'">';
181
- $file_abspath = wfu_path_rel2abs($filerec->filepath);
182
- $file_relpath = ( substr($filerec->filepath, 0, 4) == 'abs:' ? substr($filerec->filepath, 4) : $filerec->filepath );
183
- $displayed_data = array(
184
- "file" => wfu_hide_credentials_from_ftpurl($file_relpath),
185
- "date" => get_date_from_gmt($initialrec->date_from),
186
- "user" => wfu_get_username_by_id($filerec->uploaduserid),
187
- "properties" => '',
188
- "remarks" => '<div class="wfu-remarks-container"></div>',
189
- "actions" => ''
190
- );
191
- $properties = wfu_init_uploadedfiles_properties();
192
- $actions = wfu_init_uploadedfiles_actions();
193
- $remarks = '';
194
- //check if file is stored in FTP location
195
- $file_in_ftp = ( substr($file_abspath, 0, 6) == 'ftp://' || substr($file_abspath, 0, 7) == 'ftps://' || substr($file_abspath, 0, 7) == 'sftp://' );
196
- //check if file resides inside WP root
197
- $file_in_root = ( !$file_in_ftp && substr($file_abspath, 0, strlen($abspath_notrailing_slash)) == $abspath_notrailing_slash );
198
- //check if file exists for non-ftp uploads
199
- $file_exists = wfu_file_exists($file_abspath, "wfu_uploadedfiles_manager");
200
- //check if record is obsolete
201
- $obsolete = ( $filerec->date_to != "0000-00-00 00:00:00" );
202
- //check if file is associated with Media item
203
- $has_media = ( $file_in_root && $file_exists && !$obsolete && isset($filedata["media"]) );
204
-
205
- //update properties
206
- $properties['status']['icon'] = ( $file_exists ? ( $obsolete ? "obsolete" : "ok" ) : "notexists" );
207
- $properties['userdata']['visible'] = ( count(wfu_get_userdata_from_rec($filerec)) > 0 );
208
- if ( $has_media ) {
209
- $properties['media']['visible'] = true;
210
- $properties['media']['remarks'] = 'File is associated with Media item ID <strong>'.$filedata["media"]["attach_id"].'</strong>';
211
- }
212
- $properties['ftp']['visible'] = $file_in_ftp;
213
- /**
214
- * Customize Uploaded File Properties.
215
- *
216
- * This filter allows scripts to customize the list of properties of an
217
- * uploaded file.
218
- *
219
- * @since 4.8.0
220
- *
221
- * @param array $properties The list of properties of the file.
222
- * @param object $filerec The database record of the uploaded file.
223
- * @param integer $i The file's index in the list of uploaded files.
224
- */
225
- $properties = apply_filters("_wfu_uploadefiles_file_properties", $properties, $filerec, $i);
226
-
227
- //update actions
228
- $details_href_net = $siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=file_details&file=byID:'.$filerec->idlog;
229
- if ( $actions['details']['allowed'] ) {
230
- $actions['details']['visible'] = true;
231
- $actions['details']['href'] = $details_href_net.'&invoker='.$nopagecode;
232
- }
233
- $media_href = null;
234
- if ( $has_media && $actions['media']['allowed'] ) {
235
- $actions['media']['visible'] = true;
236
- $media_href = get_attachment_link( $filedata["media"]["attach_id"] );
237
- $actions['media']['href'] = $media_href;
238
- }
239
- $adminbrowser_href = false;
240
- if ( $file_in_root && $file_exists && !$obsolete && $actions['adminbrowser']['allowed'] ) {
241
- $only_path = wfu_basedir($file_relpath);
242
- $dir_code = wfu_prepare_to_batch_safe_store_filepath($only_path.'{{'.wfu_basename($file_relpath).'}}');
243
- $adminbrowser_href = $siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=file_browser&dir='.$dir_code;
244
- $actions['adminbrowser']['visible'] = true;
245
- $actions['adminbrowser']['href'] = $adminbrowser_href;
246
- }
247
- $historylog_href = $siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=view_log&invoker='.$initialrec->idlog;
248
- if ( $actions['historylog']['allowed'] ) {
249
- $actions['historylog']['visible'] = true;
250
- $actions['historylog']['href'] = $historylog_href;
251
- }
252
- $link_href = ( $file_in_root ? site_url().( substr($file_relpath, 0, 1) == '/' ? '' : '/' ) : '' ).$file_relpath;
253
- if ( $file_in_root && $file_exists && !$obsolete && $actions['link']['allowed'] ) {
254
- $actions['link']['visible'] = true;
255
- $actions['link']['href'] = $link_href;
256
- }
257
- $download_href = false;
258
- if ( $file_exists && !$obsolete && $actions['download']['allowed'] ) {
259
- $file_code = wfu_prepare_to_batch_safe_store_filepath(wfu_path_abs2rel($file_abspath));
260
- $download_href = 'javascript:wfu_download_file(\''.$file_code.'\', '.$i.');';
261
- $actions['download']['visible'] = true;
262
- $actions['download']['href'] = $download_href;
263
- $actions['download']['newtab'] = false;
264
- }
265
- /**
266
- * Customize Uploaded File Actions.
267
- *
268
- * This filter allows scripts to customize the list of actions of an
269
- * uploaded file.
270
- *
271
- * @since 4.8.0
272
- *
273
- * @param array $actions The list of actions of the file.
274
- * @param object $filerec The database record of the uploaded file.
275
- * @param integer $i The file's index in the list of uploaded files.
276
- */
277
- $actions = apply_filters("_wfu_uploadefiles_file_actions", $actions, $filerec, $i);
278
-
279
- //update default file link action
280
- $default_link = $displayed_data["file"];
281
- if ( WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "details" )
282
- $default_link = '<a href="'.$details_href_net.'&invoker='.$pagecode.'" title="Go to file details">'.$file_relpath.'</a>';
283
- elseif ( $file_in_root && $file_exists && !$obsolete && WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "adminbrowser" ) {
284
- if ( $adminbrowser_href === false ) {
285
- $only_path = wfu_basedir($file_relpath);
286
- $dir_code = wfu_prepare_to_batch_safe_store_filepath($only_path.'{{'.wfu_basename($file_relpath).'}}');
287
- $adminbrowser_href = $siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=file_browser&dir='.$dir_code;
288
- }
289
- $default_link = '<a href="'.$adminbrowser_href.'" title="Open file in File Browser">'.$file_relpath.'</a>';
290
- }
291
- elseif ( WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "historylog" )
292
- $default_link = '<a href="'.$historylog_href.'" title="Go to View Log record of file">'.$file_relpath.'</a>';
293
- elseif ( ( $file_in_ftp || $file_in_root ) && $file_exists && !$obsolete && WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "link" )
294
- $default_link = '<a href="'.$link_href.'" title="Open file link">'.$file_relpath.'</a>';
295
- elseif ( !$file_in_ftp && $file_exists && !$obsolete && WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "download" ) {
296
- if ( $download_href === false ) {
297
- $file_code = wfu_prepare_to_batch_safe_store_filepath(wfu_path_abs2rel($file_abspath));
298
- $download_href = 'javascript:wfu_download_file(\''.$file_code.'\', '.$i.');';
299
- }
300
- $default_link = '<a href="'.$download_href.'" title="Download file">'.$file_relpath.'</a>';
301
- }
302
- /**
303
- * Customize Default File Link.
304
- *
305
- * This filter allows scripts to customize the default file link action
306
- * of an uploaded file.
307
- *
308
- * @since 4.8.0
309
- *
310
- * @param string $default_link The default file link action.
311
- * @param object $filerec The database record of the uploaded file.
312
- * @param integer $i The file's index in the list of uploaded files.
313
- */
314
- $default_link = apply_filters("_wfu_uploadefiles_file_link", $default_link, $filerec, $i);
315
-
316
- $displayed_data["file"] = $default_link;
317
- $displayed_data["properties"] = wfu_render_uploadedfiles_properties($properties, $i);
318
- $displayed_data["actions"] = wfu_render_uploadedfiles_actions($actions);
319
- $echo_str .= "\n\t\t\t\t\t".'<th style="word-wrap: break-word;"'.( $id_visible ? '' : ' class="hidden"' ).'>'.$i.'</th>';
320
- $echo_str .= "\n\t\t\t\t\t".'<td class="column-primary" data-colname="File">'.$displayed_data["file"];
321
- $echo_str .= "\n\t\t\t\t\t\t".'<div id="wfu_file_download_container_'.$i.'" style="display: none;"></div>';
322
- if ( $visible_cols_count > 0 ) $echo_str .= "\n\t\t\t\t\t\t".'<button type="button" class="toggle-row"><span class="screen-reader-text">Show more details</span></button>';
323
- $echo_str .= "\n\t\t\t\t\t".'</td>';
324
- foreach ( $cols as $col => $is_visible )
325
- if ( $col == 'upload_date' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Upload Date"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["date"].'</td>';
326
- elseif ( $col == 'user' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="User"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["user"].'</td>';
327
- elseif ( $col == 'properties' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Properties"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["properties"].'</td>';
328
- elseif ( $col == 'remarks' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Remarks"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["remarks"].'</td>';
329
- elseif ( $col == 'actions' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Actions"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["actions"].'</td>';
330
- $echo_str .= "\n\t\t\t\t".'</tr>';
331
- }
332
- //store file paths to safe
333
- wfu_batch_safe_store_filepaths();
334
- if ( !$only_table_rows ) {
335
- $echo_str .= "\n\t\t\t".'</tbody>';
336
- $echo_str .= "\n\t\t".'</table>';
337
- $echo_str .= "\n\t".'</div>';
338
- $handler = 'function() { wfu_attach_uploadedfiles_events(); }';
339
- $echo_str .= "\n\t".'<script type="text/javascript">if(window.addEventListener) { window.addEventListener("load", '.$handler.', false); } else if(window.attachEvent) { window.attachEvent("onload", '.$handler.'); } else { window["onload"] = '.$handler.'; }</script>';
340
- $echo_str .= "\n".'</div>';
341
- }
342
-
343
- /**
344
- * Customize Uploaded Files Page Output.
345
- *
346
- * This filter allows scripts to customize the HTML code of Uploaded Files
347
- * Dashboard page.
348
- *
349
- * @since 4.8.0
350
- *
351
- * @param string $echo_str The HTML code of Uploaded Files page.
352
- * @param integer $page The current shown page of uploaded files list.
353
- * @param bool $only_table_rows Return only HTML code of table rows.
354
- */
355
- $echo_str = apply_filters("_wfu_uploadedfiles_output", $echo_str, $page, $only_table_rows);
356
- return $echo_str;
357
- }
358
-
359
- /**
360
- * Get List of Uploaded Files.
361
- *
362
- * This function returns the list of uploaded files to be displayed in Uploaded
363
- * Files Dashboard page.
364
- *
365
- * @since 4.9.1
366
- *
367
- * @redeclarable
368
- *
369
- * @param integer $page The page number where the uploaded files belong.
370
- *
371
- * @return array An array holding the list of uploaded files.
372
- */
373
- function wfu_uploadedfiles_get_filerecs($page) {
374
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
375
- global $wpdb;
376
- $table_name1 = $wpdb->prefix . "wfu_log";
377
- $maxrows = (int)WFU_VAR("WFU_UPLOADEDFILES_TABLE_MAXROWS");
378
- $ret = array(
379
- "files_total" => 0,
380
- "filerecs" => array(),
381
- "has_history" => false
382
- );
383
-
384
- if ( WFU_VAR("WFU_UPLOADEDFILES_HIDEINVALID") != "true" ) {
385
- $ret["files_total"] = $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1.' WHERE action = \'upload\'');
386
- $ret["filerecs"] = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action = \'upload\' ORDER BY date_from DESC'.( $maxrows > 0 ? ' LIMIT '.$maxrows.' OFFSET '.(($page - 1) * $maxrows) : '' ));
387
- }
388
- else {
389
- $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action = \'upload\' ORDER BY date_from DESC');
390
- foreach ( $filerecs as $ind => $filerec ) {
391
- $initialrec = $filerec;
392
- //get all newer associated file records
393
- $historyrecs = wfu_get_rec_new_history($initialrec->idlog);
394
- //get the latest record of this upload
395
- $filerec = $historyrecs[count($historyrecs) - 1];
396
- $file_abspath = wfu_path_rel2abs($filerec->filepath);
397
- //check if file is stored in FTP location
398
- $file_in_ftp = ( substr($file_abspath, 0, 6) == 'ftp://' || substr($file_abspath, 0, 7) == 'ftps://' || substr($file_abspath, 0, 7) == 'sftp://' );
399
- //check if file exists for non-ftp uploads
400
- $file_exists = ( $file_in_ftp ? true : wfu_file_exists($file_abspath, "wfu_uploadedfiles_get_filerecs") );
401
- //check if record is obsolete
402
- $obsolete = ( $filerec->date_to != "0000-00-00 00:00:00" );
403
- if ( !$file_exists || $obsolete ) unset($filerecs[$ind]);
404
- else $filerecs[$ind]->history = $historyrecs;
405
- }
406
- $ret["files_total"] = count($filerecs);
407
- if ( $maxrows > 0 ) $filerecs = array_slice($filerecs, ($page - 1) * $maxrows, $maxrows);
408
- $ret["filerecs"] = $filerecs;
409
- $ret["has_history"] = true;
410
- }
411
-
412
- return $ret;
413
- }
414
-
415
- /**
416
- * Generate Default List of Properties of an Uploaded File.
417
- *
418
- * This function generates the list of default properties of an uploaded file.
419
- * Each property has an icon, a title (when the mouse hovers over the icon) and
420
- * remarks (shown in Remarks column when the mouse hovers over the icon).
421
- *
422
- * @since 4.7.0
423
- *
424
- * @return array An array of properties of an uploaded file.
425
- */
426
- function wfu_init_uploadedfiles_properties() {
427
- $props["status"] = array(
428
- "icon" => "obsolete",
429
- "icon-list" => array(
430
- "ok" => "dashicons-yes",
431
- "notexists" => "dashicons-trash",
432
- "obsolete" => "dashicons-warning"
433
- ),
434
- "title" => "",
435
- "title-list" => array(
436
- "ok" => "File is Ok",
437
- "notexists" => "File does not exist",
438
- "obsolete" => "Record is invalid"
439
- ),
440
- "visible" => true,
441
- "remarks" => '',
442
- "remarks-list" => array(
443
- "ok" => "File uploaded successfully to the website",
444
- "notexists" => "File does not exist anymore in the website",
445
- "obsolete" => "Record is not valid anymore"
446
- ),
447
- "code" => wfu_create_random_string(6)
448
- );
449
- $props["userdata"] = array(
450
- "icon" => "dashicons-id-alt",
451
- "title" => "File has user data",
452
- "visible" => false,
453
- "remarks" => 'File has user data, accessible in File Details',
454
- "code" => wfu_create_random_string(6)
455
- );
456
- $props["media"] = array(
457
- "icon" => "dashicons-admin-media",
458
- "title" => "File is associated with Media item",
459
- "visible" => false,
460
- "remarks" => 'File is associated with Media item',
461
- "code" => wfu_create_random_string(6)
462
- );
463
- $props["ftp"] = array(
464
- "icon" => "wfu-dashicons-ftp",
465
- "title" => "File saved in FTP",
466
- "visible" => false,
467
- "remarks" => 'File has been saved in FTP location',
468
- "code" => wfu_create_random_string(6)
469
- );
470
-
471
- return $props;
472
- }
473
-
474
- /**
475
- * Generate Default List of Actions of an Uploaded File.
476
- *
477
- * This function generates the list of default actions of an uploaded file. Each
478
- * action has an icon, a title (when the mouse hovers over the icon) and a link
479
- * URL (the action itself).
480
- *
481
- * @since 4.7.0
482
- *
483
- * @return array An array of properties of an uploaded file.
484
- */
485
- function wfu_init_uploadedfiles_actions() {
486
- $def_actions["details"] = array(
487
- "icon" => "dashicons-info",
488
- "title" => "View file details",
489
- "allowed" => false,
490
- "visible" => false,
491
- "href" => "",
492
- "newtab" => true,
493
- "color" => "default"
494
- );
495
- $def_actions["media"] = array(
496
- "icon" => "wfu-dashicons-media-external",
497
- "title" => "Open associated Media item",
498
- "allowed" => false,
499
- "visible" => false,
500
- "href" => "",
501
- "newtab" => true,
502
- "color" => "default"
503
- );
504
- $def_actions["adminbrowser"] = array(
505
- "icon" => "dashicons-portfolio",
506
- "title" => "Locate file in File Browser",
507
- "allowed" => false,
508
- "visible" => false,
509
- "href" => "",
510
- "newtab" => true,
511
- "color" => "default"
512
- );
513
- $def_actions["historylog"] = array(
514
- "icon" => "dashicons-backup",
515
- "title" => "Locate file record in View Log",
516
- "allowed" => false,
517
- "visible" => false,
518
- "href" => "",
519
- "newtab" => true,
520
- "color" => "default"
521
- );
522
- $def_actions["link"] = array(
523
- "icon" => "dashicons-external",
524
- "title" => "Open file link",
525
- "allowed" => false,
526
- "visible" => false,
527
- "href" => "",
528
- "newtab" => true,
529
- "color" => "default"
530
- );
531
- $def_actions["download"] = array(
532
- "icon" => "dashicons-download",
533
- "title" => "Download file",
534
- "allowed" => false,
535
- "visible" => false,
536
- "href" => "",
537
- "newtab" => true,
538
- "color" => "default"
539
- );
540
-
541
- //get visible actions and their order
542
- $actions = array();
543
- $actions_raw = explode(',', WFU_VAR("WFU_UPLOADEDFILES_ACTIONS"));
544
- //normalize action list
545
- foreach ( $actions_raw as $ind => $action ) $actions_raw[$ind] = strtolower(trim($action));
546
- //generate associative array of actions adjusting order and 'allowed'
547
- //property
548
- foreach ( $actions_raw as $ind => $action )
549
- if ( isset($def_actions[$action]) ) {
550
- $actions[$action] = $def_actions[$action];
551
- $actions[$action]['allowed'] = true;
552
- unset($def_actions[$action]);
553
- }
554
- foreach ( $def_actions as $action => $props ) $actions[$action] = $props;
555
-
556
- return $actions;
557
- }
558
-
559
- /**
560
- * Display Properties of an Uploaded File.
561
- *
562
- * This function generates the HTML code of the properties of an uploaded file
563
- * that will be shown in Properties column.
564
- *
565
- * @since 4.7.0
566
- *
567
- * @redeclarable
568
- *
569
- * @param array $props The properties of the uploaded file.
570
- * @param integer $index The index of the uploaded file.
571
- *
572
- * @return string The HTML code of the properties of an uploaded file.
573
- */
574
- function wfu_render_uploadedfiles_properties($props, $index) {
575
- $a = func_get_args(); switch(WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out)) { case 'X': break; case 'R': return $out; break; case 'D': die($out); break; }
576
- $i = 0;
577
- $echo_str = "";
578
- foreach ( $props as $key => $prop ) {
579
- $ii = $i + 1;
580
- $iconclass = $prop['icon'];
581
- if ( isset($prop['icon-list']) ) $iconclass = $prop['icon-list'][$prop['icon']];
582
- $title = $prop['title'];
583
- if ( isset($prop['title-list']) ) $title = $prop['title-list'][$prop['icon']];
584
- $remarks = $prop['remarks'];
585
- if ( isset($prop['remarks-list']) ) $remarks = $prop['remarks-list'][$prop['icon']];
586
- $echo_str .= '<div id="p_'.$index.'_'.$ii.'" class="wfu-properties dashicons '.$iconclass.( $i == 0 ? '' : ' wfu-dashicons-after' ).( $prop['visible'] ? '' : ' wfu-dashicons-hidden' ).'" title="'.$title.'"><input type="hidden" class="wfu-remarks" value="'.wfu_plugin_encode_string($remarks).'" /></div>';
587
- $i ++;
588
- }
589
-
590
- return $echo_str;
591
- }
592
-
593
- /**
594
- * Display Actions of an Uploaded File.
595
- *
596
- * This function generates the HTML code of the actions of an uploaded file that
597
- * will be shown in Actions column.
598
- *
599
- * @since 4.7.0
600
- *
601
- * @redeclarable
602
- *
603
- * @param array $actions The actions of the uploaded file.
604
- *
605
- * @return string The HTML code of the actions of an uploaded file.
606
- */
607
- function wfu_render_uploadedfiles_actions($actions) {
608
- $a = func_get_args(); switch(WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out)) { case 'X': break; case 'R': return $out; break; case 'D': die($out); break; }
609
- $i = 0;
610
- $echo_str = "";
611
- foreach ( $actions as $key => $action ) {
612
- $iconclass = $action['icon'];
613
- if ( isset($action['icon-list']) ) $iconclass = $action['icon-list'][$action['icon']];
614
- $title = $action['title'];
615
- if ( isset($action['title-list']) ) $title = $action['title-list'][$action['icon']];
616
- $echo_str .= '<a class="dashicons '.$iconclass.( $i == 0 ? '' : ' wfu-dashicons-after' ).( $action['visible'] ? '' : ' wfu-dashicons-hidden' ).'" href="'.$action['href'].'" target="'.( !isset($action['newtab']) || $action['newtab'] ? '_blank' : '_self' ).'" title="'.$title.'"'.( isset($action['color']) && $action['color'] != 'default' ? ' style="color:'.$action['color'].';"' : '' ).'></a>';
617
- $i ++;
618
- }
619
-
620
- return $echo_str;
621
- }
622
-
623
- /**
624
- * Display Unread Uploaded File in Admin Bar.
625
- *
626
- * This function displays the number of unread uploaded files in Admin Bar.
627
- *
628
- * @since 4.8.0
629
- */
630
- function wfu_admin_toolbar_new_uploads() {
631
- global $wp_admin_bar;
632
- $is_admin = current_user_can( 'manage_options' );
633
-
634
- if ( $is_admin && WFU_VAR("WFU_UPLOADEDFILES_BARMENU") == "true" ) {
635
- //get the number of new (unread) uploaded files
636
- $unread_files_count = wfu_get_unread_files_count();
637
- $text = $unread_files_count;
638
- if ( $unread_files_count > 99 ) $text = "99+";
639
- $title = ( $unread_files_count == 0 ? 'No new files uploaded' : ( $unread_files_count == 1 ? '1 new file uploaded' : $unread_files_count.' files uploaded' ) );
640
-
641
- $args = array(
642
- 'id' => 'wfu_uploads',
643
- 'title' => '<span class="ab-icon"></span><span class="ab-label">'.$unread_files_count.'</span><span class="screen-reader-text">'.$title.'</span>',
644
- 'href' => admin_url( 'admin.php?page=wfu_uploaded_files' ),
645
- 'group' => false,
646
- 'meta' => array(
647
- 'title' => $title,
648
- 'class' => ( $unread_files_count == 0 && WFU_VAR("WFU_UPLOADEDFILES_BARAUTOHIDE") == "true" ? 'hidden' : '' )
649
- ),
650
- );
651
- $wp_admin_bar->add_menu( $args );
652
- }
653
- }
654
-
655
- /**
656
- * Display Files Per Page in Uploaded Files Screen Options.
657
- *
658
- * This function displays the number of uploaded files per page to display in
659
- * the screen options section of Uploaded Files Dashboard page.
660
- *
661
- * @since 4.8.0
662
- */
663
- function wfu_uploadedfiles_screen_options() {
664
- global $wfu_uploadedfiles_hook_suffix;
665
-
666
- $screen = get_current_screen();
667
- // get out of here if we are not on uploadedfiles page
668
- if( !is_object($screen) || $screen->id != $wfu_uploadedfiles_hook_suffix ) return;
669
-
670
- $args = array(
671
- 'label' => 'Files per page',
672
- 'default' => WFU_VAR("WFU_UPLOADEDFILES_TABLE_MAXROWS"),
673
- 'option' => 'wfu_uploadedfiles_per_page'
674
- );
675
- add_screen_option( 'per_page', $args );
676
  }
1
+ <?php
2
+
3
+ /**
4
+ * Uploaded Files Page in Dashboard Area of Plugin
5
+ *
6
+ * This file contains functions related to Uploaded Files page of plugin's
7
+ * Dashboard area.
8
+ *
9
+ * @link /lib/wfu_admin_uploadedfiles.php
10
+ *
11
+ * @package WordPress File Upload Plugin
12
+ * @subpackage Core Components
13
+ * @since 4.7.0
14
+ */
15
+
16
+ /**
17
+ * Process Dashboard Requests for Uploaded Files Page
18
+ *
19
+ * This function processes Dashboard requests and shows main Uploaded Files page
20
+ * of the plugin.
21
+ *
22
+ * @since 4.7.0
23
+ */
24
+ function wfu_uploadedfiles_menu() {
25
+ $_GET = stripslashes_deep($_GET);
26
+ $tag = (!empty($_GET['tag']) ? $_GET['tag'] : '1');
27
+ $page = max((int)$tag, 1);
28
+ echo wfu_uploadedfiles_manager($page);
29
+ }
30
+
31
+ /**
32
+ * Display the Uploaded Files Page.
33
+ *
34
+ * This function displays the Uploaded Files page of the plugin.
35
+ *
36
+ * @since 4.7.0
37
+ *
38
+ * @param integer $page Optional. The page to display in case contents are
39
+ * paginated.
40
+ * @param bool $only_table_rows Optional. Return only the HTML code of the table
41
+ * rows.
42
+ *
43
+ * @return string The HTML output of the plugin's Uploaded Files Dashboard page.
44
+ */
45
+ function wfu_uploadedfiles_manager($page = 1, $only_table_rows = false) {
46
+ global $wpdb;
47
+ $table_name1 = $wpdb->prefix . "wfu_log";
48
+ $table_name3 = $wpdb->prefix . "wfu_dbxqueue";
49
+ $def_other_cols = array( 'upload_date', 'user', 'properties', 'remarks', 'actions' );
50
+
51
+ if ( !current_user_can( 'manage_options' ) ) return;
52
+
53
+ $siteurl = site_url();
54
+ $maxrows = (int)WFU_VAR("WFU_UPLOADEDFILES_TABLE_MAXROWS");
55
+
56
+ //get log data from database
57
+ //$files_total = $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1.' WHERE action = \'upload\'');
58
+ //$filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action = \'upload\' ORDER BY date_from DESC'.( $maxrows > 0 ? ' LIMIT '.$maxrows.' OFFSET '.(($page - 1) * $maxrows) : '' ));
59
+ $files_total = 0;
60
+ $filerecs = array();
61
+ $has_history = false;
62
+ extract(wfu_uploadedfiles_get_filerecs($page));
63
+
64
+ //get last record already read
65
+ $last_idlog = get_option( "wordpress_file_upload_last_idlog", array( "pre" => 0, "post" => 0, "time" => 0 ) );
66
+
67
+ //get visible columns and their order
68
+ $cols = array();
69
+ $cols_raw = explode(',', WFU_VAR("WFU_UPLOADEDFILES_COLUMNS"));
70
+ //normalize column list
71
+ foreach ( $cols_raw as $ind => $col ) $cols_raw[$ind] = strtolower(trim($col));
72
+ //check if '#' column is visible
73
+ $id_visible = in_array('#', $cols_raw);
74
+ //'file' column is always visible and follows '#' column
75
+ //create an associative array $cols where keys are the columns and values
76
+ //are either true for visible columns or false for hidden ones
77
+ $visible_cols_count = 0;
78
+ foreach ( $cols_raw as $col )
79
+ if ( ($key = array_search($col, $def_other_cols)) !== false ) {
80
+ unset($def_other_cols[$key]);
81
+ $cols[$col] = true;
82
+ $visible_cols_count ++;
83
+ }
84
+ foreach ( $def_other_cols as $col ) $cols[$col] = false;
85
+
86
+ //prepare html
87
+ $echo_str = "";
88
+ if ( !$only_table_rows ) {
89
+ //Update last_idlog option so that next time Uploaded Files menu item is
90
+ //pressed files have been read.
91
+ //Option last_idlog requires a minimum interval of some seconds, defined
92
+ //by advanced variable WFU_UPLOADEDFILES_RESET_TIME, before it can be
93
+ //updated. This way, if the admin presses Uploaded Files menu item two
94
+ //times immediately, the same number of unread files will not change.
95
+ //It is noted that last_idlog option uses two values, 'pre' and 'post'.
96
+ //The way they are updated makes sure that the number of unread files
97
+ //gets reset only when Uploaded Files menu item is pressed and not
98
+ //when the admin browses through the pages of the list (when pagination
99
+ //is activated).
100
+ $limit = (int)WFU_VAR("WFU_UPLOADEDFILES_RESET_TIME");
101
+ if ( $limit == -1 || time() > $last_idlog["time"] + $limit ) {
102
+ $last_idlog["pre"] = $last_idlog["post"];
103
+ $last_idlog["post"] = $wpdb->get_var('SELECT MAX(idlog) FROM '.$table_name1);
104
+ $last_idlog["time"] = time();
105
+ update_option( "wordpress_file_upload_last_idlog", $last_idlog );
106
+ }
107
+
108
+ $echo_str .= "\n".'<div class="wrap">';
109
+ $echo_str .= "\n\t".'<h2>List of Uploaded Files</h2>';
110
+ $echo_str .= "\n\t".'<div style="position:relative;">';
111
+ $echo_str .= wfu_add_loading_overlay("\n\t\t", "uploadedfiles");
112
+ $echo_str .= "\n\t\t".'<div class="wfu_uploadedfiles_header" style="width: 100%;">';
113
+ if ( $maxrows > 0 ) {
114
+ $pages = ceil($files_total / $maxrows);
115
+ $echo_str .= wfu_add_pagination_header("\n\t\t\t", "uploadedfiles", $page, $pages);
116
+ }
117
+ $echo_str .= "\n\t\t\t".'<input id="wfu_download_file_nonce" type="hidden" value="'.wp_create_nonce('wfu_download_file_invoker').'" />';
118
+ $echo_str .= "\n\t\t".'</div>';
119
+ $echo_str .= "\n\t\t".'<table id="wfu_uploadedfiles_table" class="wfu-uploadedfiles wp-list-table widefat fixed striped">';
120
+ $echo_str .= "\n\t\t\t".'<thead>';
121
+ $echo_str .= "\n\t\t\t\t".'<tr>';
122
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="5%" class="manage-column'.( $id_visible ? '' : ' hidden' ).'">';
123
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>#</label>';
124
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
125
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="30%" class="manage-column column-primary">';
126
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>File</label>';
127
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
128
+ foreach ( $cols as $col => $is_visible ) {
129
+ if ( $col == 'upload_date' ) {
130
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
131
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>Upload Date</label>';
132
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
133
+ }
134
+ elseif ( $col == 'user' ) {
135
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
136
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>User</label>';
137
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
138
+ }
139
+ elseif ( $col == 'properties' ) {
140
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
141
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>Properties</label>';
142
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
143
+ }
144
+ elseif ( $col == 'remarks' ) {
145
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="25%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
146
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>Remarks</label>';
147
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
148
+ }
149
+ elseif ( $col == 'actions' ) {
150
+ $echo_str .= "\n\t\t\t\t\t".'<th scope="col" width="10%" class="manage-column'.( $is_visible ? '' : ' hidden' ).'">';
151
+ $echo_str .= "\n\t\t\t\t\t\t".'<label>Actions</label>';
152
+ $echo_str .= "\n\t\t\t\t\t".'</th>';
153
+ }
154
+ }
155
+ $echo_str .= "\n\t\t\t\t".'</tr>';
156
+ $echo_str .= "\n\t\t\t".'</thead>';
157
+ $echo_str .= "\n\t\t\t".'<tbody>';
158
+ }
159
+ //echo the number of unread uploaded files in order to update the
160
+ //notification bubble of the toplevel menu item
161
+ $unread_files_count = wfu_get_new_files_count($last_idlog["pre"]);
162
+ $echo_str .= "\n\t\t\t".'<!-- wfu_uploadedfiles_unread['.$unread_files_count.'] -->';
163
+
164
+ $i = ($page - 1) * $maxrows;
165
+ $abspath_notrailing_slash = substr(wfu_abspath(), 0, -1);
166
+ $pagecode = wfu_safe_store_browser_params('wfu_uploaded_files&tag='.$page);
167
+ $nopagecode = wfu_safe_store_browser_params('no_referer');
168
+ foreach ( $filerecs as $filerec ) {
169
+ $i ++;
170
+ $initialrec = $filerec;
171
+ //get all newer associated file records
172
+ $historyrecs = array();
173
+ if ( $has_history ) $historyrecs = $filerec->history;
174
+ else $historyrecs = wfu_get_rec_new_history($initialrec->idlog);
175
+ //get the latest record of this upload
176
+ $filerec = $historyrecs[count($historyrecs) - 1];
177
+ $filedata = wfu_get_filedata_from_rec($filerec, false, true, false);
178
+ if ( $filedata == null ) $filedata = array();
179
+
180
+ $echo_str .= "\n\t\t\t\t".'<tr class="wfu_row-'.$i.( $initialrec->idlog > $last_idlog["pre"] ? ' wfu_unread' : '' ).'">';
181
+ $file_abspath = wfu_path_rel2abs($filerec->filepath);
182
+ $file_relpath = ( substr($filerec->filepath, 0, 4) == 'abs:' ? substr($filerec->filepath, 4) : $filerec->filepath );
183
+ $remote = wfu_check_file_remote_basic($file_abspath);
184
+ $displayed_data = array(
185
+ "file" => wfu_hide_credentials_from_ftpurl($file_relpath),
186
+ "date" => get_date_from_gmt($initialrec->date_from),
187
+ "user" => wfu_get_username_by_id($filerec->uploaduserid),
188
+ "properties" => '',
189
+ "remarks" => '<div class="wfu-remarks-container"></div>',
190
+ "actions" => ''
191
+ );
192
+ $properties = wfu_init_uploadedfiles_properties();
193
+ $actions = wfu_init_uploadedfiles_actions();
194
+ $remarks = '';
195
+ //check if file is stored in FTP location
196
+ $file_in_ftp = ( substr($file_abspath, 0, 6) == 'ftp://' || substr($file_abspath, 0, 7) == 'ftps://' || substr($file_abspath, 0, 7) == 'sftp://' );
197
+ //check if file resides inside WP root
198
+ $file_in_root = ( !$file_in_ftp && substr($file_abspath, 0, strlen($abspath_notrailing_slash)) == $abspath_notrailing_slash );
199
+ $file_is_local = !$file_in_ftp;
200
+ //check if record is obsolete
201
+ $obsolete = ( $filerec->date_to != "0000-00-00 00:00:00" );
202
+ //check if file exists for non-obsolete or local uploads
203
+ $file_exists = ( !$obsolete || $file_is_local ? wfu_file_exists($file_abspath, "wfu_uploadedfiles_manager") : false );
204
+ //check if file is associated with Media item
205
+ $has_media = ( $file_in_root && $file_exists && !$obsolete && isset($filedata["media"]) );
206
+
207
+ //update properties
208
+ $properties['status']['icon'] = ( $file_exists ? ( $obsolete ? "obsolete" : "ok" ) : "notexists" );
209
+ $properties['userdata']['visible'] = ( count(wfu_get_userdata_from_rec($filerec)) > 0 );
210
+ if ( $has_media ) {
211
+ $properties['media']['visible'] = true;
212
+ $properties['media']['remarks'] = 'File is associated with Media item ID <strong>'.$filedata["media"]["attach_id"].'</strong>';
213
+ }
214
+ $properties['ftp']['visible'] = $file_in_ftp;
215
+ /**
216
+ * Customize Uploaded File Properties.
217
+ *
218
+ * This filter allows scripts to customize the list of properties of an
219
+ * uploaded file.
220
+ *
221
+ * @since 4.8.0
222
+ *
223
+ * @param array $properties The list of properties of the file.
224
+ * @param object $filerec The database record of the uploaded file.
225
+ * @param integer $i The file's index in the list of uploaded files.
226
+ */
227
+ $properties = apply_filters("_wfu_uploadefiles_file_properties", $properties, $filerec, $i);
228
+
229
+ //update actions
230
+ $details_href_net = $siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=file_details&file=byID:'.$filerec->idlog;
231
+ if ( $actions['details']['allowed'] ) {
232
+ $actions['details']['visible'] = true;
233
+ $actions['details']['href'] = $details_href_net.'&invoker='.$nopagecode;
234
+ }
235
+ $media_href = null;
236
+ if ( $has_media && $actions['media']['allowed'] ) {
237
+ $actions['media']['visible'] = true;
238
+ $media_href = get_attachment_link( $filedata["media"]["attach_id"] );
239
+ $actions['media']['href'] = $media_href;
240
+ }
241
+ $adminbrowser_href = false;
242
+ if ( $file_in_root && $file_exists && !$obsolete && $actions['adminbrowser']['allowed'] ) {
243
+ $only_path = wfu_basedir($file_relpath);
244
+ $dir_code = wfu_prepare_to_batch_safe_store_filepath($only_path.'{{'.wfu_basename($file_relpath).'}}');
245
+ $adminbrowser_href = $siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=file_browser&dir='.$dir_code;
246
+ $actions['adminbrowser']['visible'] = true;
247
+ $actions['adminbrowser']['href'] = $adminbrowser_href;
248
+ }
249
+ $historylog_href = $siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=view_log&invoker='.$initialrec->idlog;
250
+ if ( $actions['historylog']['allowed'] ) {
251
+ $actions['historylog']['visible'] = true;
252
+ $actions['historylog']['href'] = $historylog_href;
253
+ }
254
+ $link_href = ( $file_in_root ? site_url().( substr($file_relpath, 0, 1) == '/' ? '' : '/' ) : '' ).$file_relpath;
255
+ if ( $file_in_root && $file_exists && !$obsolete && $actions['link']['allowed'] ) {
256
+ $actions['link']['visible'] = true;
257
+ $actions['link']['href'] = $link_href;
258
+ }
259
+ $download_href = false;
260
+ if ( $file_exists && !$obsolete && !$remote && $actions['download']['allowed'] ) {
261
+ $file_code = wfu_prepare_to_batch_safe_store_filepath(wfu_path_abs2rel($file_abspath));
262
+ $download_href = 'javascript:wfu_download_file(\''.$file_code.'\', '.$i.');';
263
+ $actions['download']['visible'] = true;
264
+ $actions['download']['href'] = $download_href;
265
+ $actions['download']['newtab'] = false;
266
+ }
267
+ /**
268
+ * Customize Uploaded File Actions.
269
+ *
270
+ * This filter allows scripts to customize the list of actions of an
271
+ * uploaded file.
272
+ *
273
+ * @since 4.8.0
274
+ *
275
+ * @param array $actions The list of actions of the file.
276
+ * @param object $filerec The database record of the uploaded file.
277
+ * @param integer $i The file's index in the list of uploaded files.
278
+ */
279
+ $actions = apply_filters("_wfu_uploadefiles_file_actions", $actions, $filerec, $i);
280
+
281
+ //update default file link action
282
+ $default_link = $displayed_data["file"];
283
+ if ( WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "details" )
284
+ $default_link = '<a href="'.$details_href_net.'&invoker='.$pagecode.'" title="Go to file details">'.$file_relpath.'</a>';
285
+ elseif ( $file_in_root && $file_exists && !$obsolete && WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "adminbrowser" ) {
286
+ if ( $adminbrowser_href === false ) {
287
+ $only_path = wfu_basedir($file_relpath);
288
+ $dir_code = wfu_prepare_to_batch_safe_store_filepath($only_path.'{{'.wfu_basename($file_relpath).'}}');
289
+ $adminbrowser_href = $siteurl.'/wp-admin/options-general.php?page=wordpress_file_upload&action=file_browser&dir='.$dir_code;
290
+ }
291
+ $default_link = '<a href="'.$adminbrowser_href.'" title="Open file in File Browser">'.$file_relpath.'</a>';
292
+ }
293
+ elseif ( WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "historylog" )
294
+ $default_link = '<a href="'.$historylog_href.'" title="Go to View Log record of file">'.$file_relpath.'</a>';
295
+ elseif ( ( $file_in_ftp || $file_in_root ) && $file_exists && !$obsolete && WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "link" )
296
+ $default_link = '<a href="'.$link_href.'" title="Open file link">'.$file_relpath.'</a>';
297
+ elseif ( !$file_in_ftp && $file_exists && !$obsolete && WFU_VAR("WFU_UPLOADEDFILES_DEFACTION") == "download" ) {
298
+ if ( $download_href === false ) {
299
+ $file_code = wfu_prepare_to_batch_safe_store_filepath(wfu_path_abs2rel($file_abspath));
300
+ $download_href = 'javascript:wfu_download_file(\''.$file_code.'\', '.$i.');';
301
+ }
302
+ $default_link = '<a href="'.$download_href.'" title="Download file">'.$file_relpath.'</a>';
303
+ }
304
+ /**
305
+ * Customize Default File Link.
306
+ *
307
+ * This filter allows scripts to customize the default file link action
308
+ * of an uploaded file.
309
+ *
310
+ * @since 4.8.0
311
+ *
312
+ * @param string $default_link The default file link action.
313
+ * @param object $filerec The database record of the uploaded file.
314
+ * @param integer $i The file's index in the list of uploaded files.
315
+ */
316
+ $default_link = apply_filters("_wfu_uploadefiles_file_link", $default_link, $filerec, $i);
317
+
318
+ $displayed_data["file"] = $default_link;
319
+ $displayed_data["properties"] = wfu_render_uploadedfiles_properties($properties, $i);
320
+ $displayed_data["actions"] = wfu_render_uploadedfiles_actions($actions);
321
+ $echo_str .= "\n\t\t\t\t\t".'<th style="word-wrap: break-word;"'.( $id_visible ? '' : ' class="hidden"' ).'>'.$i.'</th>';
322
+ $echo_str .= "\n\t\t\t\t\t".'<td class="column-primary" data-colname="File">'.$displayed_data["file"];
323
+ $echo_str .= "\n\t\t\t\t\t\t".'<div id="wfu_file_download_container_'.$i.'" style="display: none;"></div>';
324
+ if ( $visible_cols_count > 0 ) $echo_str .= "\n\t\t\t\t\t\t".'<button type="button" class="toggle-row"><span class="screen-reader-text">Show more details</span></button>';
325
+ $echo_str .= "\n\t\t\t\t\t".'</td>';
326
+ foreach ( $cols as $col => $is_visible )
327
+ if ( $col == 'upload_date' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Upload Date"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["date"].'</td>';
328
+ elseif ( $col == 'user' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="User"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["user"].'</td>';
329
+ elseif ( $col == 'properties' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Properties"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["properties"].'</td>';
330
+ elseif ( $col == 'remarks' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Remarks"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["remarks"].'</td>';
331
+ elseif ( $col == 'actions' ) $echo_str .= "\n\t\t\t\t\t".'<td data-colname="Actions"'.( $is_visible ? '' : ' class="hidden"' ).'>'.$displayed_data["actions"].'</td>';
332
+ $echo_str .= "\n\t\t\t\t".'</tr>';
333
+ }
334
+ //store file paths to safe
335
+ wfu_batch_safe_store_filepaths();
336
+ if ( !$only_table_rows ) {
337
+ $echo_str .= "\n\t\t\t".'</tbody>';
338
+ $echo_str .= "\n\t\t".'</table>';
339
+ $echo_str .= "\n\t".'</div>';
340
+ $handler = 'function() { wfu_attach_uploadedfiles_events(); }';
341
+ $echo_str .= "\n\t".'<script type="text/javascript">if(window.addEventListener) { window.addEventListener("load", '.$handler.', false); } else if(window.attachEvent) { window.attachEvent("onload", '.$handler.'); } else { window["onload"] = '.$handler.'; }</script>';
342
+ $echo_str .= "\n".'</div>';
343
+ }
344
+
345
+ /**
346
+ * Customize Uploaded Files Page Output.
347
+ *
348
+ * This filter allows scripts to customize the HTML code of Uploaded Files
349
+ * Dashboard page.
350
+ *
351
+ * @since 4.8.0
352
+ *
353
+ * @param string $echo_str The HTML code of Uploaded Files page.
354
+ * @param integer $page The current shown page of uploaded files list.
355
+ * @param bool $only_table_rows Return only HTML code of table rows.
356
+ */
357
+ $echo_str = apply_filters("_wfu_uploadedfiles_output", $echo_str, $page, $only_table_rows);
358
+ return $echo_str;
359
+ }
360
+
361
+ /**
362
+ * Get List of Uploaded Files.
363
+ *
364
+ * This function returns the list of uploaded files to be displayed in Uploaded
365
+ * Files Dashboard page.
366
+ *
367
+ * @since 4.9.1
368
+ *
369
+ * @redeclarable
370
+ *
371
+ * @param integer $page The page number where the uploaded files belong.
372
+ *
373
+ * @return array An array holding the list of uploaded files.
374
+ */
375
+ function wfu_uploadedfiles_get_filerecs($page) {
376
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
377
+ global $wpdb;
378
+ $table_name1 = $wpdb->prefix . "wfu_log";
379
+ $maxrows = (int)WFU_VAR("WFU_UPLOADEDFILES_TABLE_MAXROWS");
380
+ $ret = array(
381
+ "files_total" => 0,
382
+ "filerecs" => array(),
383
+ "has_history" => false
384
+ );
385
+
386
+ if ( WFU_VAR("WFU_UPLOADEDFILES_HIDEINVALID") != "true" ) {
387
+ $ret["files_total"] = $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1.' WHERE action = \'upload\'');
388
+ $ret["filerecs"] = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action = \'upload\' ORDER BY date_from DESC'.( $maxrows > 0 ? ' LIMIT '.$maxrows.' OFFSET '.(($page - 1) * $maxrows) : '' ));
389
+ }
390
+ else {
391
+ $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action = \'upload\' ORDER BY date_from DESC');
392
+ foreach ( $filerecs as $ind => $filerec ) {
393
+ $initialrec = $filerec;
394
+ //get all newer associated file records
395
+ $historyrecs = wfu_get_rec_new_history($initialrec->idlog);
396
+ //get the latest record of this upload
397
+ $filerec = $historyrecs[count($historyrecs) - 1];
398
+ $file_abspath = wfu_path_rel2abs($filerec->filepath);
399
+ //check if record is obsolete
400
+ $obsolete = ( $filerec->date_to != "0000-00-00 00:00:00" );
401
+ //remove record if it is obsolete or file does not exist
402
+ if ( $obsolete || !wfu_file_exists($file_abspath, "wfu_uploadedfiles_get_filerecs") ) unset($filerecs[$ind]);
403
+ else $filerecs[$ind]->history = $historyrecs;
404
+ }
405
+ $ret["files_total"] = count($filerecs);
406
+ if ( $maxrows > 0 ) $filerecs = array_slice($filerecs, ($page - 1) * $maxrows, $maxrows);
407
+ $ret["filerecs"] = $filerecs;
408
+ $ret["has_history"] = true;
409
+ }
410
+
411
+ return $ret;
412
+ }
413
+
414
+ /**
415
+ * Generate Default List of Properties of an Uploaded File.
416
+ *
417
+ * This function generates the list of default properties of an uploaded file.
418
+ * Each property has an icon, a title (when the mouse hovers over the icon) and
419
+ * remarks (shown in Remarks column when the mouse hovers over the icon).
420
+ *
421
+ * @since 4.7.0
422
+ *
423
+ * @return array An array of default properties of an uploaded file.
424
+ */
425
+ function wfu_init_uploadedfiles_properties() {
426
+ $props["status"] = array(
427
+ "icon" => "obsolete",
428
+ "icon-list" => array(
429
+ "ok" => "dashicons-yes",
430
+ "notexists" => "dashicons-trash",
431
+ "obsolete" => "dashicons-warning"
432
+ ),
433
+ "title" => "",
434
+ "title-list" => array(
435
+ "ok" => "File is Ok",
436
+ "notexists" => "File does not exist",
437
+ "obsolete" => "Record is invalid"
438
+ ),
439
+ "visible" => true,
440
+ "remarks" => '',
441
+ "remarks-list" => array(
442
+ "ok" => "File uploaded successfully to the website",
443
+ "notexists" => "File does not exist anymore in the website",
444
+ "obsolete" => "Record is not valid anymore"
445
+ ),
446
+ "code" => wfu_create_random_string(6)
447
+ );
448
+ $props["userdata"] = array(
449
+ "icon" => "dashicons-id-alt",
450
+ "title" => "File has user data",
451
+ "visible" => false,
452
+ "remarks" => 'File has user data, accessible in File Details',
453
+ "code" => wfu_create_random_string(6)
454
+ );
455
+ $props["media"] = array(
456
+ "icon" => "dashicons-admin-media",
457
+ "title" => "File is associated with Media item",
458
+ "visible" => false,
459
+ "remarks" => 'File is associated with Media item',
460
+ "code" => wfu_create_random_string(6)
461
+ );
462
+ $props["ftp"] = array(
463
+ "icon" => "wfu-dashicons-ftp",
464
+ "title" => "File saved in FTP",
465
+ "visible" => false,
466
+ "remarks" => 'File has been saved in FTP location',
467
+ "code" => wfu_create_random_string(6)
468
+ );
469
+
470
+ return $props;
471
+ }
472
+
473
+ /**
474
+ * Generate Default List of Actions of an Uploaded File.
475
+ *
476
+ * This function generates the list of default actions of an uploaded file. Each
477
+ * action has an icon, a title (when the mouse hovers over the icon) and a link
478
+ * URL (the action itself).
479
+ *
480
+ * @since 4.7.0
481
+ *
482
+ * @return array An array of default actions of an uploaded file.
483
+ */
484
+ function wfu_init_uploadedfiles_actions() {
485
+ $def_actions["details"] = array(
486
+ "icon" => "dashicons-info",
487
+ "title" => "View file details",
488
+ "allowed" => false,
489
+ "visible" => false,
490
+ "href" => "",
491
+ "newtab" => true,
492
+ "color" => "default"
493
+ );
494
+ $def_actions["media"] = array(
495
+ "icon" => "wfu-dashicons-media-external",
496
+ "title" => "Open associated Media item",
497
+ "allowed" => false,
498
+ "visible" => false,
499
+ "href" => "",
500
+ "newtab" => true,
501
+ "color" => "default"
502
+ );
503
+ $def_actions["adminbrowser"] = array(
504
+ "icon" => "dashicons-portfolio",
505
+ "title" => "Locate file in File Browser",
506
+ "allowed" => false,
507
+ "visible" => false,
508
+ "href" => "",
509
+ "newtab" => true,
510
+ "color" => "default"
511
+ );
512
+ $def_actions["historylog"] = array(
513
+ "icon" => "dashicons-backup",
514
+ "title" => "Locate file record in View Log",
515
+ "allowed" => false,
516
+ "visible" => false,
517
+ "href" => "",
518
+ "newtab" => true,
519
+ "color" => "default"
520
+ );
521
+ $def_actions["link"] = array(
522
+ "icon" => "dashicons-external",
523
+ "title" => "Open file link",
524
+ "allowed" => false,
525
+ "visible" => false,
526
+ "href" => "",
527
+ "newtab" => true,
528
+ "color" => "default"
529
+ );
530
+ $def_actions["download"] = array(
531
+ "icon" => "dashicons-download",
532
+ "title" => "Download file",
533
+ "allowed" => false,
534
+ "visible" => false,
535
+ "href" => "",
536
+ "newtab" => true,
537
+ "color" => "default"
538
+ );
539
+
540
+ //get visible actions and their order
541
+ $actions = array();
542
+ $actions_raw = explode(',', WFU_VAR("WFU_UPLOADEDFILES_ACTIONS"));
543
+ //normalize action list
544
+ foreach ( $actions_raw as $ind => $action ) $actions_raw[$ind] = strtolower(trim($action));
545
+ //generate associative array of actions adjusting order and 'allowed'
546
+ //property
547
+ foreach ( $actions_raw as $ind => $action )
548
+ if ( isset($def_actions[$action]) ) {
549
+ $actions[$action] = $def_actions[$action];
550
+ $actions[$action]['allowed'] = true;
551
+ unset($def_actions[$action]);
552
+ }
553
+ foreach ( $def_actions as $action => $props ) $actions[$action] = $props;
554
+
555
+ return $actions;
556
+ }
557
+
558
+ /**
559
+ * Display Properties of an Uploaded File.
560
+ *
561
+ * This function generates the HTML code of the properties of an uploaded file
562
+ * that will be shown in Properties column.
563
+ *
564
+ * @since 4.7.0
565
+ *
566
+ * @redeclarable
567
+ *
568
+ * @param array $props The properties of the uploaded file.
569
+ * @param integer $index The index of the uploaded file.
570
+ *
571
+ * @return string The HTML code of the properties of an uploaded file.
572
+ */
573
+ function wfu_render_uploadedfiles_properties($props, $index) {
574
+ $a = func_get_args(); switch(WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out)) { case 'X': break; case 'R': return $out; break; case 'D': die($out); break; }
575
+ $i = 0;
576
+ $echo_str = "";
577
+ foreach ( $props as $key => $prop ) {
578
+ $ii = $i + 1;
579
+ $iconclass = $prop['icon'];
580
+ if ( isset($prop['icon-list']) ) $iconclass = $prop['icon-list'][$prop['icon']];
581
+ $title = $prop['title'];
582
+ if ( isset($prop['title-list']) ) $title = $prop['title-list'][$prop['icon']];
583
+ $remarks = $prop['remarks'];
584
+ if ( isset($prop['remarks-list']) ) $remarks = $prop['remarks-list'][$prop['icon']];
585
+ $echo_str .= '<div id="p_'.$index.'_'.$ii.'" class="wfu-properties dashicons '.$iconclass.( $i == 0 ? '' : ' wfu-dashicons-after' ).( $prop['visible'] ? '' : ' wfu-dashicons-hidden' ).'" title="'.$title.'"><input type="hidden" class="wfu-remarks" value="'.wfu_plugin_encode_string($remarks).'" /></div>';
586
+ $i ++;
587
+ }
588
+
589
+ return $echo_str;
590
+ }
591
+
592
+ /**
593
+ * Display Actions of an Uploaded File.
594
+ *
595
+ * This function generates the HTML code of the actions of an uploaded file that
596
+ * will be shown in Actions column.
597
+ *
598
+ * @since 4.7.0
599
+ *
600
+ * @redeclarable
601
+ *
602
+ * @param array $actions The actions of the uploaded file.
603
+ *
604
+ * @return string The HTML code of the actions of an uploaded file.
605
+ */
606
+ function wfu_render_uploadedfiles_actions($actions) {
607
+ $a = func_get_args(); switch(WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out)) { case 'X': break; case 'R': return $out; break; case 'D': die($out); break; }
608
+ $i = 0;
609
+ $echo_str = "";
610
+ foreach ( $actions as $key => $action ) {
611
+ $iconclass = $action['icon'];
612
+ if ( isset($action['icon-list']) ) $iconclass = $action['icon-list'][$action['icon']];
613
+ $title = $action['title'];
614
+ if ( isset($action['title-list']) ) $title = $action['title-list'][$action['icon']];
615
+ $echo_str .= '<a class="dashicons '.$iconclass.( $i == 0 ? '' : ' wfu-dashicons-after' ).( $action['visible'] ? '' : ' wfu-dashicons-hidden' ).'" href="'.$action['href'].'" target="'.( !isset($action['newtab']) || $action['newtab'] ? '_blank' : '_self' ).'" title="'.$title.'"'.( isset($action['color']) && $action['color'] != 'default' ? ' style="color:'.$action['color'].';"' : '' ).'></a>';
616
+ $i ++;
617
+ }
618
+
619
+ return $echo_str;
620
+ }
621
+
622
+ /**
623
+ * Display Unread Uploaded File in Admin Bar.
624
+ *
625
+ * This function displays the number of unread uploaded files in Admin Bar.
626
+ *
627
+ * @since 4.8.0
628
+ */
629
+ function wfu_admin_toolbar_new_uploads() {
630
+ global $wp_admin_bar;
631
+ $is_admin = current_user_can( 'manage_options' );
632
+
633
+ if ( $is_admin && WFU_VAR("WFU_UPLOADEDFILES_BARMENU") == "true" ) {
634
+ //get the number of new (unread) uploaded files
635
+ $unread_files_count = wfu_get_unread_files_count();
636
+ $text = $unread_files_count;
637
+ if ( $unread_files_count > 99 ) $text = "99+";
638
+ $title = ( $unread_files_count == 0 ? 'No new files uploaded' : ( $unread_files_count == 1 ? '1 new file uploaded' : $unread_files_count.' files uploaded' ) );
639
+
640
+ $args = array(
641
+ 'id' => 'wfu_uploads',
642
+ 'title' => '<span class="ab-icon"></span><span class="ab-label">'.$unread_files_count.'</span><span class="screen-reader-text">'.$title.'</span>',
643
+ 'href' => admin_url( 'admin.php?page=wfu_uploaded_files' ),
644
+ 'group' => false,
645
+ 'meta' => array(
646
+ 'title' => $title,
647
+ 'class' => ( $unread_files_count == 0 && WFU_VAR("WFU_UPLOADEDFILES_BARAUTOHIDE") == "true" ? 'hidden' : '' )
648
+ ),
649
+ );
650
+ $wp_admin_bar->add_menu( $args );
651
+ }
652
+ }
653
+
654
+ /**
655
+ * Display Files Per Page in Uploaded Files Screen Options.
656
+ *
657
+ * This function displays the number of uploaded files per page to display in
658
+ * the screen options section of Uploaded Files Dashboard page.
659
+ *
660
+ * @since 4.8.0
661
+ */
662
+ function wfu_uploadedfiles_screen_options() {
663
+ global $wfu_uploadedfiles_hook_suffix;
664
+
665
+ $screen = get_current_screen();
666
+ // get out of here if we are not on uploadedfiles page
667
+ if( !is_object($screen) || $screen->id != $wfu_uploadedfiles_hook_suffix ) return;
668
+
669
+ $args = array(
670
+ 'label' => 'Files per page',
671
+ 'default' => WFU_VAR("WFU_UPLOADEDFILES_TABLE_MAXROWS"),
672
+ 'option' => 'wfu_uploadedfiles_per_page'
673
+ );
674
+ add_screen_option( 'per_page', $args );
 
675
  }
lib/wfu_constants.php CHANGED
@@ -1,522 +1,530 @@
1
- <?php
2
-
3
- /**
4
- * Constants and Strings of Plugin
5
- *
6
- * This file initializes all constants and translatable strings of the plugin.
7
- *
8
- * @link /lib/wfu_constants.php
9
- *
10
- * @package WordPress File Upload Plugin
11
- * @subpackage Core Components
12
- * @since 2.1.2
13
- */
14
-
15
- $siteurl = site_url();
16
-
17
- /**
18
- * Translatable Strings Initialization.
19
- *
20
- * This function initializes all translatable strings of the plugin.
21
- *
22
- * @since 4.7.0
23
- */
24
- function wfu_initialize_i18n_strings() {
25
- if ( defined("WFU_I18_LOADED") ) return;
26
- DEFINE("WFU_I18_LOADED", 1);
27
- //plugin default values
28
- DEFINE("WFU_UPLOADTITLE", __('Upload files', 'wp-file-upload'));
29
- DEFINE("WFU_SELECTBUTTON", __('Select File', 'wp-file-upload'));
30
- DEFINE("WFU_UPLOADBUTTON", __('Upload File', 'wp-file-upload'));
31
- DEFINE("WFU_NOTIFYSUBJECT", __('File Upload Notification', 'wp-file-upload'));
32
- DEFINE("WFU_NOTIFYMESSAGE", __("Dear Recipient,%n%%n% This is an automatic delivery message to notify you that a new file has been uploaded.%n%%n%Best Regards", 'wp-file-upload'));
33
- DEFINE("WFU_SUCCESSMESSAGE", __('File %filename% uploaded successfully', 'wp-file-upload'));
34
- DEFINE("WFU_WARNINGMESSAGE", __('File %filename% uploaded successfully but with warnings', 'wp-file-upload'));
35
- DEFINE("WFU_ERRORMESSAGE", __('File %filename% not uploaded', 'wp-file-upload'));
36
- DEFINE("WFU_WAITMESSAGE", __('File %filename% is being uploaded', 'wp-file-upload'));
37
- DEFINE("WFU_USERDATALABEL", __('Your message', 'wp-file-upload')."|t:text|s:left|r:0|a:0|p:inline|d:");
38
- DEFINE("WFU_CAPTCHAPROMPT", __('Please fill in the above words: ', 'wp-file-upload'));
39
- DEFINE("WFU_UPLOADMEDIABUTTON", __('Upload Media', 'wp-file-upload'));
40
- DEFINE("WFU_VIDEONAME", __('videostream', 'wp-file-upload'));
41
- DEFINE("WFU_IMAGENAME", __('screenshot', 'wp-file-upload'));
42
- DEFINE("WFU_CONSENTQUESTION", __('By activating this option I agree to let the website keep my personal data', 'wp-file-upload'));
43
- DEFINE("WFU_CONSENTREJECTMESSAGE", __('You have denied to let the website keep your personal data. Upload cannot continue!', 'wp-file-upload'));
44
- DEFINE("WFU_CONSENTYES", __('Yes', 'wp-file-upload'));
45
- DEFINE("WFU_CONSENTNO", __('No', 'wp-file-upload'));
46
- //browser default values
47
- DEFINE("WFU_FILETITLE", __('File', 'wp-file-upload'));
48
- DEFINE("WFU_DATETITLE", __('Date', 'wp-file-upload'));
49
- DEFINE("WFU_SIZETITLE", __('Size', 'wp-file-upload'));
50
- DEFINE("WFU_USERTITLE", __('User', 'wp-file-upload'));
51
- DEFINE("WFU_POSTTITLE", __('Page', 'wp-file-upload'));
52
- DEFINE("WFU_FIELDSTITLE", __('User Fields', 'wp-file-upload'));
53
- DEFINE("WFU_DOWNLOADLABEL", __('Download', 'wp-file-upload'));
54
- DEFINE("WFU_DOWNLOADTITLE", __('Download this file', 'wp-file-upload'));
55
- DEFINE("WFU_DELETELABEL", __('Delete', 'wp-file-upload'));
56
- DEFINE("WFU_DELETETITLE", __('Delete this file', 'wp-file-upload'));
57
- DEFINE("WFU_REMOVEREMOTELABEL", __('Remove Remote', 'wp-file-upload'));
58
- DEFINE("WFU_REMOVEREMOTETITLE", __('Remove this remote file', 'wp-file-upload'));
59
- DEFINE("WFU_SORTTITLE", __('Sort list based on this column', 'wp-file-upload'));
60
- DEFINE("WFU_GUESTTITLE", __('guest', 'wp-file-upload'));
61
- DEFINE("WFU_UNKNOWNTITLE", __('unknown', 'wp-file-upload'));
62
- //error messages
63
- DEFINE("WFU_ERROR_ADMIN_FTPDIR_RESOLVE", __("Error. Could not resolve ftp target filedir. Check the domain in 'ftpinfo' attribute.", "wp-file-upload"));
64
- DEFINE("WFU_ERROR_ADMIN_FTPINFO_INVALID", __("Error. Invalid ftp information. Check 'ftpinfo' attribute.", "wp-file-upload"));
65
- DEFINE("WFU_ERROR_ADMIN_FTPINFO_EXTRACT", __("Error. Could not extract ftp information from 'ftpinfo' attribute. Check its syntax.", "wp-file-upload"));
66
- DEFINE("WFU_ERROR_ADMIN_FTPFILE_RESOLVE", __("Error. Could not resolve ftp target filename. Check the domain in 'ftpinfo' attribute.", "wp-file-upload"));
67
- DEFINE("WFU_ERROR_ADMIN_FTPSOURCE_FAIL", __("Error. Could not open source file for ftp upload. Check if file is accessible.", "wp-file-upload"));
68
- DEFINE("WFU_ERROR_ADMIN_FTPTRANSFER_FAIL", __("Error. Could not send data to ftp target file.", "wp-file-upload"));
69
- DEFINE("WFU_ERROR_ADMIN_FTPHOST_FAIL", __("Error. Could not connect to ftp host. Check the domain in 'ftpinfo' attribute.", "wp-file-upload"));
70
- DEFINE("WFU_ERROR_ADMIN_FTPLOGIN_FAIL", __("Error. Could not authenticate to ftp host. Check username and password in 'ftpinfo' attribute.", "wp-file-upload"));
71
- DEFINE("WFU_ERROR_ADMIN_SFTPINIT_FAIL", __("Error. Could not initialize sftp subsystem. Please check if the server supports sftp.", "wp-file-upload"));
72
- DEFINE("WFU_ERROR_ADMIN_SFTP_UNSUPPORTED", __("Error. The web server does not support sftp.", "wp-file-upload"));
73
- DEFINE("WFU_ERROR_ADMIN_FILE_PHP_SIZE", __("Error. The upload size limit of PHP directive upload_max_filesize is preventing the upload of big files.\nPHP directive upload_max_filesize limit is: ".ini_get("upload_max_filesize").".\nTo increase the limit change the value of the directive from php.ini.\nIf you don't have access to php.ini, then try adding the following line to your .htaccess file:\n\nphp_value upload_max_filesize 10M\n\n(adjust the size according to your needs)\n\nThe file .htaccess is found in your website root directory (where index.php is found).\nIf your don't have this file, then create it.\nIf this does not work either, then contact your domain provider.", "wp-file-upload"));
74
- DEFINE("WFU_ERROR_ADMIN_FILE_PHP_TIME", __("The upload time limit of PHP directive max_input_time is preventing the upload of big files.\nPHP directive max_input_time limit is: ".ini_get("max_input_time")." seconds.\nTo increase the limit change the value of the directive from php.ini.\nIf you don't have access to php.ini, then add the following line to your .htaccess file:\n\nphp_value max_input_time 500\n\n(adjust the time according to your needs)\n\nThe file .htaccess is found in your website root directory (where index.php is found).\nIf your don't have this file, then create it.\nIf this does not work either, then contact your domain provider.", "wp-file-upload"));
75
- DEFINE("WFU_ERROR_ADMIN_DIR_PERMISSION", __("Error. Permission denied to write to target folder.\nCheck and correct read/write permissions of target folder.", "wp-file-upload"));
76
- DEFINE("WFU_ERROR_ADMIN_FILE_WRONGEXT", __("Error. This file was rejected because its extension is not correct. Its proper filename is: ", "wp-file-upload"));
77
- DEFINE("WFU_ERROR_ADMIN_FILE_NOIMAGE", __("Error. This file was rejected because its not a valid image.", "wp-file-upload"));
78
- DEFINE("WFU_ERROR_ADMIN_DOS_ATTACK", __("Too many files are uploaded in a short period of time. This may be a Denial-Of-Service attack, so file was rejected. Please check the upload log for suspicious behaviour.", "wp-file-upload"));
79
- DEFINE("WFU_ERROR_DOS_ATTACK", __("File not uploaded in order to prevent overflow of the website. Please contact administrator.", "wp-file-upload"));
80
- DEFINE("WFU_ERROR_DIR_EXIST", __("Target folder doesn't exist.", "wp-file-upload"));
81
- DEFINE("WFU_ERROR_DIR_NOTEMP", __("Upload failed! Missing a temporary folder.", "wp-file-upload"));
82
- DEFINE("WFU_ERROR_DIR_PERMISSION", __("Upload failed! Permission denied to write to target folder.", "wp-file-upload"));
83
- DEFINE("WFU_ERROR_FILE_ALLOW", __("File not allowed.", "wp-file-upload"));
84
- DEFINE("WFU_ERROR_FILE_REJECT", __("File is suspicious and was rejected.", "wp-file-upload"));
85
- DEFINE("WFU_ERROR_FILE_PLUGIN_SIZE", __("The uploaded file exceeds the file size limit.", "wp-file-upload"));
86
- DEFINE("WFU_ERROR_FILE_PLUGIN_2GBSIZE", __("The uploaded file exceeds 2GB and is not supported by this server.", "wp-file-upload"));
87
- DEFINE("WFU_ERROR_FILE_PHP_SIZE", __("Upload failed! The uploaded file exceeds the file size limit of the server. Please contact the administrator.", "wp-file-upload"));
88
- DEFINE("WFU_ERROR_FILE_PHP_TIME", __("Upload failed! The duration of the upload exceeded the time limit of the server. Please contact the administrator.", "wp-file-upload"));
89
- DEFINE("WFU_ERROR_FILE_HTML_SIZE", __("Upload failed! The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.", "wp-file-upload"));
90
- DEFINE("WFU_ERROR_FILE_PARTIAL", __("Upload failed! The uploaded file was only partially uploaded.", "wp-file-upload"));
91
- DEFINE("WFU_ERROR_FILE_NOTHING", __("Upload failed! No file was uploaded.", "wp-file-upload"));
92
- DEFINE("WFU_ERROR_FILE_WRITE", __("Upload failed! Failed to write file to disk.", "wp-file-upload"));
93
- DEFINE("WFU_ERROR_FILE_MOVE", __("Upload failed! Error occured while moving temporary file. Please contact administrator.", "wp-file-upload"));
94
- DEFINE("WFU_ERROR_FILE_CANCELLED", __("Upload cancelled!", "wp-file-upload"));
95
- DEFINE("WFU_ERROR_UPLOAD_STOPPED", __("Upload failed! A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help.", "wp-file-upload"));
96
- DEFINE("WFU_ERROR_UPLOAD_FAILED_WHILE", __("Upload failed! Error occured while attemting to upload the file.", "wp-file-upload"));
97
- DEFINE("WFU_ERROR_UPLOAD_FAILED", __("Upload failed!", "wp-file-upload"));
98
- DEFINE("WFU_ERROR_UPLOAD_NOFILESELECTED", __("No file!", "wp-file-upload"));
99
- DEFINE("WFU_ERROR_UPLOAD_CANCELLED", __("Upload failed! The upload has been canceled by the user or the browser dropped the connection.", "wp-file-upload"));
100
- DEFINE("WFU_ERROR_UNKNOWN", __("Upload failed! Unknown error.", "wp-file-upload"));
101
- DEFINE("WFU_ERROR_CONTACT_ADMIN", __("Please contact the administrator.", "wp-file-upload"));
102
- DEFINE("WFU_ERROR_REMOTESERVER_NORESULT", __("No result from remote server!", "wp-file-upload"));
103
- DEFINE("WFU_ERROR_JSONPARSE_FILEMESSAGE", __(" but with warnings", "wp-file-upload"));
104
- DEFINE("WFU_ERROR_JSONPARSE_MESSAGE", __("Warning: JSON parse error.", "wp-file-upload"));
105
- DEFINE("WFU_ERROR_JSONPARSE_ADMINMESSAGE", __("Upload parameters of this file, passed as JSON string to the handler, could not be parsed.", "wp-file-upload"));
106
- DEFINE("WFU_ERROR_JSONPARSE_HEADERMESSAGE", __("Warning: JSON parse error.", "wp-file-upload"));
107
- DEFINE("WFU_ERROR_JSONPARSE_HEADERADMINMESSAGE", __("UploadStates, passed as JSON string to the handler, could not be parsed.", "wp-file-upload"));
108
- DEFINE("WFU_ERROR_REDIRECTION_ERRORCODE0", __("Redirection to classic form functionality occurred due to unknown error.", "wp-file-upload"));
109
- DEFINE("WFU_ERROR_REDIRECTION_ERRORCODE1", __("Redirection to classic form functionality occurred because AJAX is not supported.", "wp-file-upload"));
110
- DEFINE("WFU_ERROR_REDIRECTION_ERRORCODE2", __("Redirection to classic form functionality occurred because HTML5 is not supported.", "wp-file-upload"));
111
- DEFINE("WFU_ERROR_REDIRECTION_ERRORCODE3", __("Redirection to classic form functionality occurred due to JSON parse error.", "wp-file-upload"));
112
- DEFINE("WFU_ERROR_ENABLE_POPUPS", __("Please enable popup windows from the browser's settings!", "wp-file-upload"));
113
- DEFINE("WFU_ERROR_USERDATA_EMPTY", __("cannot be empty!", "wp-file-upload"));
114
- DEFINE("WFU_ERROR_USERDATANUMBER_INVALID", __("number not valid!", "wp-file-upload"));
115
- DEFINE("WFU_ERROR_USERDATAEMAIL_INVALID", __("email not valid!", "wp-file-upload"));
116
- DEFINE("WFU_ERROR_USERDATACONFIRMEMAIL_NOMATCH", __("emails do not match!", "wp-file-upload"));
117
- DEFINE("WFU_ERROR_USERDATACONFIRMEMAIL_NOBASE", __("no base email field in group!", "wp-file-upload"));
118
- DEFINE("WFU_ERROR_USERDATACONFIRMPASSWORD_NOMATCH", __("passwords do not match!", "wp-file-upload"));
119
- DEFINE("WFU_ERROR_USERDATACONFIRMPASSWORD_NOBASE", __("no base password field in group!", "wp-file-upload"));
120
- DEFINE("WFU_ERROR_USERDATACHECKBOX_NOTCHECKED", __("checkbox unchecked!", "wp-file-upload"));
121
- DEFINE("WFU_ERROR_USERDATARADIO_NOTSELECTED", __("no option selected!", "wp-file-upload"));
122
- DEFINE("WFU_ERROR_USERDATALIST_NOITEMSELECTED", __("no item selected!", "wp-file-upload"));
123
- DEFINE("WFU_ERROR_SAME_PLUGINID", __("There are more than one instances of the plugin in this page with the same id. Please change it.", "wp-file-upload"));
124
- DEFINE("WFU_ERROR_PAGE_OBSOLETE", __("Cannot edit the shortcode because the page has been modified. Please reload the page.", "wp-file-upload"));
125
- DEFINE("WFU_ERROR_WEBCAM_NOTSUPPORTED", __("Your browser does not support webcam capture!", "wp-file-upload"));
126
- DEFINE("WFU_ERROR_WEBCAM_VIDEO_NOTSUPPORTED", __("Your browser does not support video recording from the webcam!", "wp-file-upload"));
127
- DEFINE("WFU_ERROR_WEBCAM_VIDEO_NOTHINGRECORDED", __("No video was recorded!", "wp-file-upload"));
128
- DEFINE("WFU_ERROR_CAPTCHA_OLDPHP", __("ERROR: Captcha not supported! You have an old PHP version. Upgrade your PHP or use RecaptchaV2 (no account).", "wp-file-upload"));
129
- DEFINE("WFU_ERROR_CAPTCHA_MULTIPLE_NOTALLOWED", __("ERROR: Only one instance of RecaptchaV1 can exist on the same page. Please notify administrator.", "wp-file-upload"));
130
- DEFINE("WFU_ERROR_CAPTCHA_MULTIPLE_NOTALLOWED_ADMIN", __("ERROR: Only one instance of RecaptchaV1 can exist on the same page. Please use RecaptchaV1 (no account).", "wp-file-upload"));
131
- DEFINE("WFU_ERROR_CAPTCHA_NOSITEKEY", __("ERROR: No site key. Please contact administrator!", "wp-file-upload"));
132
- DEFINE("WFU_ERROR_CAPTCHA_NOSITEKEY_ADMIN", __("ERROR: No site key defined! Please go to the plugin settings in Dashboard to define Google Recaptcha keys.", "wp-file-upload"));
133
- DEFINE("WFU_ERROR_CAPTCHA_NOCHALLENGE", __("Bad captcha image!", "wp-file-upload"));
134
- DEFINE("WFU_ERROR_CAPTCHA_NOINPUT", __("No input!", "wp-file-upload"));
135
- DEFINE("WFU_ERROR_CAPTCHA_EMPTY", __("Captcha not completed!", "wp-file-upload"));
136
- DEFINE("WFU_ERROR_CAPTCHA_WRONGCAPTCHA", __("Wrong captcha!", "wp-file-upload"));
137
- DEFINE("WFU_ERROR_CAPTCHA_REFRESHING", __("Error refreshing captcha!", "wp-file-upload"));
138
- DEFINE("WFU_ERROR_CAPTCHA_UNKNOWNERROR", __("Unknown captcha error!", "wp-file-upload"));
139
- DEFINE("WFU_ERROR_CAPTCHA_NOTSUPPORTED", __("Captcha not supported by your browser!", "wp-file-upload"));
140
- DEFINE("WFU_ERROR_CAPTCHA_MISSINGINPUTSECRET", __("the secret parameter is missing", "wp-file-upload"));
141
- DEFINE("WFU_ERROR_CAPTCHA_INVALIDINPUTSECRET", __("the secret parameter is invalid or malformed", "wp-file-upload"));
142
- DEFINE("WFU_ERROR_CAPTCHA_MISSINGINPUTRESPONSE", __("the response parameter is missing", "wp-file-upload"));
143
- DEFINE("WFU_ERROR_CAPTCHA_INVALIDINPUTRESPONSE", __("the response parameter is invalid or malformed", "wp-file-upload"));
144
- DEFINE("WFU_ERROR_REDIRECTION_NODRAGDROP", __("Please do not use drag drop due to an internal problem.", "wp-file-upload"));
145
- DEFINE("WFU_ERROR_CHUNKEDUPLOAD_UNIQUEIDEMPTY", __("Error during chunked upload. Unique ID empty in chunk %d", "wp-file-upload"));
146
- DEFINE("WFU_ERROR_CHUNKEDUPLOAD_NOTALLOWED", __("Chunked upload is not allowed!", "wp-file-upload"));
147
- DEFINE("WFU_ERROR_CHUNKEDUPLOAD_ABORTED", __("Chunked upload aborted due to error in previous chunk!", "wp-file-upload"));
148
- DEFINE("WFU_ERROR_CHUNKEDUPLOAD_CONCATFAILED", __("Chunked upload failed, final file could not be created!", "wp-file-upload"));
149
- DEFINE("WFU_ERROR_ADMIN_CHUNKWRITEFAILED", __("Could not write file chuck to destination on chunk %d", "wp-file-upload"));
150
- DEFINE("WFU_ERROR_ADMIN_CHUNKENLARGEFAILED", __("Could not enlarge destination file on chunk %d", "wp-file-upload"));
151
- DEFINE("WFU_ERROR_ADMIN_CHUNKHANDLEFAILED", __("Could not open file handles on chunk %d", "wp-file-upload"));
152
- DEFINE("WFU_BROWSER_DOWNLOADFILE_NOTALLOWED", __("You are not allowed to download this file!", "wp-file-upload"));
153
- DEFINE("WFU_BROWSER_DOWNLOADFILE_NOTEXIST", __("File does not exist!", "wp-file-upload"));
154
- DEFINE("WFU_BROWSER_DOWNLOADFILE_FAILED", __("Could not download file!", "wp-file-upload"));
155
- DEFINE("WFU_BROWSER_DELETEFILE_NOTALLOWED", __("You are not allowed to delete this file!", "wp-file-upload"));
156
- DEFINE("WFU_BROWSER_DELETEFILE_FAILED", __("File was not deleted!", "wp-file-upload"));
157
- DEFINE("WFU_BROWSER_DELETEFILES_ALLFAILED", __("No file was deleted!", "wp-file-upload"));
158
- DEFINE("WFU_BROWSER_DELETEFILES_SOMEFAILED", __("Some files were not deleted!", "wp-file-upload"));
159
- //warning messages
160
- DEFINE("WFU_WARNING_FILE_EXISTS", __("Upload skipped! File already exists.", "wp-file-upload"));
161
- DEFINE("WFU_WARNING_FILE_SUSPICIOUS", __("The extension of the file does not match its contents.", "wp-file-upload"));
162
- DEFINE("WFU_WARNING_ADMIN_FILE_SUSPICIOUS", __("Upload succeeded but the file is suspicious because its contents do not match its extension. Its proper filename is: ", "wp-file-upload"));
163
- DEFINE("WFU_WARNING_NOFILES_SELECTED", __("No files have been selected!", "wp-file-upload"));
164
- DEFINE("WFU_WARNING_CONSENT_NOTCOMPLETED", __("Please complete the consent question before continuing the upload!", "wp-file-upload"));
165
- DEFINE("WFU_WARNING_WPFILEBASE_NOTUPDATED_NOFILES", __("WPFilebase Plugin not updated because there were no files uploaded.", "wp-file-upload"));
166
- DEFINE("WFU_WARNING_NOTIFY_NOTSENT_NOFILES", __("Notification email was not sent because there were no files uploaded.", "wp-file-upload"));
167
- DEFINE("WFU_WARNING_NOTIFY_NOTSENT_NORECIPIENTS", __("Notification email was not sent because no recipients were defined. Please check notifyrecipients attribute in the shortcode.", "wp-file-upload"));
168
- DEFINE("WFU_WARNING_NOTIFY_NOTSENT_UNKNOWNERROR", __("Notification email was not sent due to an error. Please check notifyrecipients, notifysubject and notifymessage attributes for errors.", "wp-file-upload"));
169
- DEFINE("WFU_WARNING_REDIRECT_NOTEXECUTED_EMPTY", __("Redirection not executed because redirection link is empty. Please check redirectlink attribute.", "wp-file-upload"));
170
- DEFINE("WFU_WARNING_REDIRECT_NOTEXECUTED_FILESFAILED", __("Redirection not executed because not all files were successfully uploaded.", "wp-file-upload"));
171
- DEFINE("WFU_WARNING_POTENTIAL_DOS_EMAIL_SUBJECT", __("Potential Denial-Of-Service Attack on {SITE}", "wp-file-upload"));
172
- DEFINE("WFU_WARNING_POTENTIAL_DOS_EMAIL_MESSAGE", __("Hello admin\n\nThis is a message from Wordpress File Upload Plugin to notify you that a potential Denial-Of-Service attack has been detected on {SITE}.\n\nThe plugin detected more than {FILENUM} uploads within {INTERVAL} seconds.\n\nAll file uploads that exceed this limit are rejected to protect the website from overflowing.\n\nPlease check the upload history log in the plugin's area in Dashboard for any suspicious behaviour.\n\nA new message will follow if the situation remains.\n\nThanks", "wp-file-upload"));
173
- DEFINE("WFU_WARNING_ALT_IPTANUS_SERVER_ACTIVATED", __("You have activated an alternative insecure Iptanus Services Server. For details please contact info@iptanus.com.", "wp-file-upload"));
174
- DEFINE("WFU_WARNING_IPTANUS_SERVER_UNREACHABLE", __("Iptanus Services Server is unreachable. This may cause problems on some plugin functions. Please read this :article: for resolution.", "wp-file-upload"));
175
- //admin area messages
176
- DEFINE("WFU_DASHBOARD_ADD_SHORTCODE_REJECTED", __("Failed to add the shortcode to the page/post. Please try again. If the message persists, contact administrator.", "wp-file-upload"));
177
- DEFINE("WFU_DASHBOARD_EDIT_SHORTCODE_REJECTED", __("Failed to edit the shortcode because the contents of the page changed. Try again to edit the shortcode.", "wp-file-upload"));
178
- DEFINE("WFU_DASHBOARD_DELETE_SHORTCODE_REJECTED", __("Failed to delete the shortcode because the contents of the page changed. Try again to delete it.", "wp-file-upload"));
179
- DEFINE("WFU_DASHBOARD_PAGE_OBSOLETE", __("The page containing the shortcode has been modified and it is no longer valid. Please go back to reload the shortcode.", "wp-file-upload"));
180
- DEFINE("WFU_DASHBOARD_UPDATE_SHORTCODE_REJECTED", __("Failed to update the shortcode because the contents of the page changed. Go back to reload the shortcode.", "wp-file-upload"));
181
- DEFINE("WFU_DASHBOARD_UPDATE_SHORTCODE_FAILED", __("Failed to update the shortcode. Please try again. If the problem persists, go back and reload the shortcode.", "wp-file-upload"));
182
- //test messages
183
- DEFINE("WFU_TESTMESSAGE_MESSAGE", __('This is a test message', 'wp-file-upload'));
184
- DEFINE("WFU_TESTMESSAGE_ADMINMESSAGE", __('This is a test administrator message', 'wp-file-upload'));
185
- DEFINE("WFU_TESTMESSAGE_FILE1_HEADER", __('File testfile 1 under test', 'wp-file-upload'));
186
- DEFINE("WFU_TESTMESSAGE_FILE1_MESSAGE", __('File testfile 1 message', 'wp-file-upload'));
187
- DEFINE("WFU_TESTMESSAGE_FILE1_ADMINMESSAGE", __('File testfile 1 administrator message', 'wp-file-upload'));
188
- DEFINE("WFU_TESTMESSAGE_FILE2_HEADER", __('File testfile 2 under test', 'wp-file-upload'));
189
- DEFINE("WFU_TESTMESSAGE_FILE2_MESSAGE", __('File testfile 2 message', 'wp-file-upload'));
190
- DEFINE("WFU_TESTMESSAGE_FILE2_ADMINMESSAGE", __('File testfile 2 administrator message', 'wp-file-upload'));
191
- //variables tool-tips
192
- DEFINE("WFU_VARIABLE_TITLE_USERID", __("Insert variable %userid% inside text. It will be replaced by the id of the current user.", "wp-file-upload"));
193
- DEFINE("WFU_VARIABLE_TITLE_USERNAME", __("Insert variable %username% inside text. It will be replaced by the username of the current user.", "wp-file-upload"));
194
- DEFINE("WFU_VARIABLE_TITLE_USEREMAIL", __("Insert variable %useremail% inside text. It will be replaced by the email of the current user.", "wp-file-upload"));
195
- DEFINE("WFU_VARIABLE_TITLE_FILENAME", __("Insert variable %filename% inside text. It will be replaced by the filename of the uploaded file.", "wp-file-upload"));
196
- DEFINE("WFU_VARIABLE_TITLE_FILEPATH", __("Insert variable %filepath% inside text. It will be replaced by the full filepath of the uploaded file.", "wp-file-upload"));
197
- DEFINE("WFU_VARIABLE_TITLE_BLOGID", __("Insert variable %blogid% inside text. It will be replaced by the blog id of the website.", "wp-file-upload"));
198
- DEFINE("WFU_VARIABLE_TITLE_PAGEID", __("Insert variable %pageid% inside text. It will be replaced by the id of the current page.", "wp-file-upload"));
199
- DEFINE("WFU_VARIABLE_TITLE_PAGETITLE", __("Insert variable %pagetitle% inside text. It will be replaced by the title of the current page.", "wp-file-upload"));
200
- DEFINE("WFU_VARIABLE_TITLE_USERDATAXXX", __("Insert variable %userdataXXX% inside text. Select the user field from the drop-down list. It will be replaced by the value that the user entered in this field.", "wp-file-upload"));
201
- DEFINE("WFU_VARIABLE_TITLE_N", __("Insert variable %n% inside text to denote a line change.", "wp-file-upload"));
202
- //other plugin values
203
- DEFINE("WFU_WARNINGMESSAGE_NOSAVE", __('File %filename% uploaded successfully but not saved', 'wp-file-upload'));
204
- DEFINE("WFU_NOTIFY_TESTMODE", __("Test Mode", "wp-file-upload"));
205
- DEFINE("WFU_SUBDIR_SELECTDIR", __("select dir...", "wp-file-upload"));
206
- DEFINE("WFU_SUBDIR_TYPEDIR", __("type dir", "wp-file-upload"));
207
- DEFINE("WFU_SUCCESSMESSAGE_DETAILS", __('Upload path: %filepath%', 'wp-file-upload'));
208
- DEFINE("WFU_FAILMESSAGE_DETAILS", __('Failed upload path: %filepath%', 'wp-file-upload'));
209
- DEFINE("WFU_USERDATA_REQUIREDLABEL", __(' (required)', 'wp-file-upload'));
210
- DEFINE("WFU_PAGEEXIT_PROMPT", __('Files are being uploaded. Are you sure you want to exit the page?', 'wp-file-upload'));
211
- DEFINE("WFU_MESSAGE_CAPTCHA_CHECKING", __("checking captcha...", "wp-file-upload"));
212
- DEFINE("WFU_MESSAGE_CAPTCHA_REFRESHING", __("refreshing...", "wp-file-upload"));
213
- DEFINE("WFU_MESSAGE_CAPTCHA_OK", __("correct captcha", "wp-file-upload"));
214
- DEFINE("WFU_CONFIRMBOX_CAPTION", __("click to continue the upload", "wp-file-upload"));
215
- DEFINE("WFU_BROWSER_DELETEFILE_PROMPT", __("Are you sure you want to delete this file?", "wp-file-upload"));
216
- DEFINE("WFU_BROWSER_DELETEFILES_PROMPT", __("Are you sure you want to delete these files?", "wp-file-upload"));
217
- DEFINE("WFU_BROWSER_BULKACTION_TITLE", __("Bulk Actions", "wp-file-upload"));
218
- DEFINE("WFU_BROWSER_BULKACTION_LABEL", __("Apply", "wp-file-upload"));
219
- DEFINE("WFU_PAGINATION_PAGE", __("Page", "wp-file-upload"));
220
- DEFINE("WFU_PAGINATION_OF", __("of ", "wp-file-upload"));
221
- DEFINE("WFU_CANCEL_UPLOAD_PROMPT", __("Are you sure that you want to cancel the upload?", "wp-file-upload"));
222
- DEFINE("WFU_FILE_CANCEL_HINT", __("cancel upload of this file", "wp-file-upload"));
223
- DEFINE("WFU_UPLOAD_STATE0", __("Upload in progress", "wp-file-upload"));
224
- DEFINE("WFU_UPLOAD_STATE1", __("Upload in progress with warnings!", "wp-file-upload"));
225
- DEFINE("WFU_UPLOAD_STATE2", __("Upload in progress but some files already failed!", "wp-file-upload"));
226
- DEFINE("WFU_UPLOAD_STATE3", __("Upload in progress but no files uploaded so far!", "wp-file-upload"));
227
- DEFINE("WFU_UPLOAD_STATE4", __("All files uploaded successfully", "wp-file-upload"));
228
- DEFINE("WFU_UPLOAD_STATE5", __("All files uploaded successfully but there are warnings!", "wp-file-upload"));
229
- DEFINE("WFU_UPLOAD_STATE5_SINGLEFILE", __("File uploaded successfully but there are warnings!", "wp-file-upload"));
230
- DEFINE("WFU_UPLOAD_STATE6", __("Some files failed to upload!", "wp-file-upload"));
231
- DEFINE("WFU_UPLOAD_STATE7", __("All files failed to upload", "wp-file-upload"));
232
- DEFINE("WFU_UPLOAD_STATE7_SINGLEFILE", __("File failed to upload", "wp-file-upload"));
233
- DEFINE("WFU_UPLOAD_STATE8", __("There are no files to upload!", "wp-file-upload"));
234
- DEFINE("WFU_UPLOAD_STATE9", __("Test upload message", "wp-file-upload"));
235
- DEFINE("WFU_UPLOAD_STATE10", __("JSON parse warning!", "wp-file-upload"));
236
- DEFINE("WFU_UPLOAD_STATE11", __("please wait while redirecting...", "wp-file-upload"));
237
- DEFINE("WFU_UPLOAD_STATE12", __("Upload failed!", "wp-file-upload"));
238
- DEFINE("WFU_UPLOAD_STATE13", __("Submitting data", "wp-file-upload"));
239
- DEFINE("WFU_UPLOAD_STATE14", __("Data submitted successfully!", "wp-file-upload"));
240
- DEFINE("WFU_UPLOAD_STATE15", __("Data were not submitted!", "wp-file-upload"));
241
- DEFINE("WFU_UPLOAD_STATE16", __("Cancelling upload", "wp-file-upload"));
242
- DEFINE("WFU_UPLOAD_STATE17", __("Upload cancelled!", "wp-file-upload"));
243
- DEFINE("WFU_UPLOAD_STATE18", __("Upload succeeded!", "wp-file-upload"));
244
- DEFINE("WFU_UPLOAD_STATE19", __("Upload completed but no files were saved!", "wp-file-upload"));
245
- DEFINE("WFU_UPLOAD_STATE19_SINGLEFILE", __("File was not saved due to personal data policy!", "wp-file-upload"));
246
- DEFINE("WFU_PAGE_PLUGINEDITOR_BUTTONTITLE", __("Open visual shortcode editor in new window", "wp-file-upload"));
247
- DEFINE("WFU_PAGE_PLUGINEDITOR_LOADING", __("loading visual editor", "wp-file-upload"));
248
- DEFINE("WFU_CONFIRM_CLEARFILES", __("Clear file list?", "wp-file-upload"));
249
- DEFINE("WFU_DROP_HERE_MESSAGE", __('DROP HERE', 'wp-file-upload'));
250
- //webcam values
251
- DEFINE("WFU_WEBCAM_RECVIDEO_BTN", __('record video', 'wp-file-upload'));
252
- DEFINE("WFU_WEBCAM_TAKEPIC_BTN", __('take a picture', 'wp-file-upload'));
253
- DEFINE("WFU_WEBCAM_TURNONOFF_BTN", __('turn webcam on/off', 'wp-file-upload'));
254
- DEFINE("WFU_WEBCAM_GOLIVE_BTN", __('go live again', 'wp-file-upload'));
255
- DEFINE("WFU_WEBCAM_STOPREC_BTN", __('end recording', 'wp-file-upload'));
256
- DEFINE("WFU_WEBCAM_PLAY_BTN", __('play', 'wp-file-upload'));
257
- DEFINE("WFU_WEBCAM_PAUSE_BTN", __('pause', 'wp-file-upload'));
258
- DEFINE("WFU_WEBCAM_GOBACK_BTN", __('go to the beginning', 'wp-file-upload'));
259
- DEFINE("WFU_WEBCAM_GOFWD_BTN", __('go to the end', 'wp-file-upload'));
260
- //widget values
261
- DEFINE("WFU_WIDGET_PLUGINFORM_TITLE", __('Wordpress File Upload Form', 'wp-file-upload'));
262
- DEFINE("WFU_WIDGET_PLUGINFORM_DESCRIPTION", __('Wordpress File Upload plugin uploader for sidebars', 'wp-file-upload'));
263
- DEFINE("WFU_WIDGET_SIDEBAR_DEFAULTTITLE", __('Upload Files', 'wp-file-upload'));
264
- }
265
-
266
- /*********** Environment Variables ************/
267
- //plugin default values
268
- $GLOBALS["WFU_GLOBALS"] = array(
269
- "WFU_UPLOADID" => array( "Default Upload ID", "string", "1", "The default upload ID of the uploader shortcode. It can be any integer from 1 and above." ),
270
- "WFU_SINGLEBUTTON" => array( "Default Single-Button Status", "string", "false", "The default single-button status of the uploader shortcode. It can be 'true' or 'false'." ),
271
- "WFU_UPLOADROLE" => array( "Default Upload Role", "string", "all,guests", "The default upload role of the uploader shortcode. It can be a comma-separated list of role slugs, including keywords 'all' and 'guests'." ),
272
- "WFU_UPLOADPATH" => array( "Default Upload Path", "string", "uploads", "The default upload path of the uploader shortcode. It must be a folder relative to wp-content dir." ),
273
- "WFU_FITMODE" => array( "Default Fit Mode", "string", "fixed", "The default fit mode of the uploader shortcode. It can be 'fixed' or 'responsive'." ),
274
- "WFU_ALLOWNOFILE" => array( "Default Allow No File Mode", "string", "false", "The default mode for allowing no file uploads. If it is set to 'true' then an upload form can be submitted even if a file has not been selected. It can be 'true' or 'false'." ),
275
- "WFU_ALLOWNOFILE" => array( "Default Allow No File Mode", "string", "false", "The default mode for allowing no file uploads. If it is set to 'true' then an upload form can be submitted even if a file has not been selected. It can be 'true' or 'false'." ),
276
- "WFU_RESETMODE" => array( "Default Reset Form Mode", "string", "always", "The default reset mode of the upload form. It can be 'always', 'onsuccess' or 'never'." ),
277
- "WFU_FORCEFILENAME" => array( "Default Force Filename State", "string", "false", "The default force filename state (force plugin to leave filename unchanged) of the uploader shortcode. It can be 'true' or 'false'." ),
278
- "WFU_UPLOADPATTERNS" => array( "Default Upload Extensions", "string", "*.*", "The default allowed file extensions of the uploader shortcode. It can be a comma-separated list of wildcard extensions." ),
279
- "WFU_MAXSIZE" => array( "Default Maximum File Size", "string", "50", "The default maximum allowed file size of the uploader shortcode in Megabytes. It can be any positive number." ),
280
- "WFU_ACCESSMETHOD" => array( "Default Access Method", "string", "normal", "The default access method (of the website filesystem) of the uploader shortcode. It can be 'normal' or 'ftp'." ),
281
- "WFU_FTPINFO" => array( "Default FTP Access Information", "string", "", "The default FTP access parameters of the uploader shortcode. It's syntax is 'username:password@ftp_domain'." ),
282
- "WFU_USEFTPDOMAIN" => array( "Default Use FTP Domain State", "string", "false", "The default use FTP domain state (use the FTP domain defined in ftpinfo to store the uploaded files) of the uploader shortcode. It can be 'true' or 'false'." ),
283
- "WFU_FTPPASSIVEMODE" => array( "Default FTP Passive Mode State", "string", "false", "The default FTP passive mode (use passive mode or not for FTP access) of the uploader shortcode. It can be 'true' or 'false'." ),
284
- "WFU_FTPFILEPERMISSIONS" => array( "Default FTP File Permissions", "string", "", "The default FTP passive mode (use passive mode or not for FTP access) of the uploader shortcode. It can be 'true' or 'false'." ),
285
- "WFU_DUBLICATESPOLICY" => array( "Default Duplicate File Action", "string", "overwrite", "The default duplicate file action of the uploader shortcode. It can be 'overwrite', 'reject' or 'mantain both'." ),
286
- "WFU_UNIQUEPATTERN" => array( "Default Duplicate File Pattern", "string", "index", "The default duplicate file pattern of the uploader shortcode. It can be 'index' or 'datetimestamp'." ),
287
- "WFU_FILEBASELINK" => array( "Default WPFilebase Update State", "string", "false", "The default WPFilebase plugin update state of the uploader shortcode. It can be 'true' or 'false'." ),
288
- "WFU_NOTIFY" => array( "Default Email Notification State", "string", "false", "The default email notification state of the uploader shortcode. It can be 'true' or 'false'." ),
289
- "WFU_NOTIFYRECIPIENTS" => array( "Default Email Recipients", "string", "", "The default email recipients of the uploader shortcode. It can be a comma-separated list of email addresses." ),
290
- "WFU_NOTIFYHEADERS" => array( "Default Email Headers", "string", "", "The default email headers of the uploader shortcode." ),
291
- "WFU_ATTACHFILE" => array( "Default Attach File State", "string", "false", "The default attach file to email state of the uploader shortcode. It can be 'true' or 'false'." ),
292
- "WFU_REDIRECT" => array( "Default Redirection State", "string", "false", "The default redirection state of the uploader shortcode. It can be 'true' or 'false'." ),
293
- "WFU_REDIRECTLINK" => array( "Default Redirect URL", "string", "", "The default redirect URL of the uploader shortcode." ),
294
- "WFU_ADMINMESSAGES" => array( "Default State for Admin Messages", "string", "false", "The default state of displaying or not admin messages of the uploader shortcode. It can be 'true' or 'false'." ),
295
- "WFU_SUCCESSMESSAGECOLORS" => array( "Default Colors for Success Message", "string", "#006600,#EEFFEE,#006666", "The default color triplet (text, background and border colors) of success message of the uploader shortcode." ),
296
- "WFU_WARNINGMESSAGECOLORS" => array( "Default Colors for Warning Message", "string", "#F88017,#FEF2E7,#633309", "The default color triplet (text, background and border colors) of warning message of the uploader shortcode." ),
297
- "WFU_FAILMESSAGECOLORS" => array( "Default Colors for Fail Message", "string", "#660000,#FFEEEE,#666600", "The default color triplet (text, background and border colors) of fail message of the uploader shortcode." ),
298
- "WFU_WAITMESSAGECOLORS" => array( "Default Colors for Wait Message", "string", "#666666,#EEEEEE,#333333", "The default color triplet (text, background and border colors) of wait message of the uploader shortcode." ),
299
- "WFU_SHOWTARGETFOLDER" => array( "Default State for Target Folder", "string", "false", "The default state of displaying or not the target folder of the uploader shortcode. It can be 'true' or 'false'." ),
300
- "WFU_TARGETFOLDERLABEL" => array( "Default Text for Target Folder Label", "string", "Upload Directory", "The default text of the target folder label of the uploader shortcode." ),
301
- "WFU_ASKFORSUBFOLDERS" => array( "Default Subfolders State", "string", "false", "The default state of displaying or not a list of subfolders of the uploader shortcode. It can be 'true' or 'false'." ),
302
- "WFU_SUBFOLDERLABEL" => array( "Default Text of Subfolders Label", "string", "Select Subfolder", "The default text of subfolders label of the uploader shortcode." ),
303
- "WFU_SUBFOLDERTREE" => array( "Default Subfolders List", "string", "", "The default list of subfolders of the uploader shortcode. Check plugin's support page for syntax." ),
304
- "WFU_FORCECLASSIC" => array( "Default Disable AJAX State", "string", "false", "The default state of disabling or not AJAX functionality of the uploader shortcode. It can be 'true' or 'false'." ),
305
- "WFU_TESTMODE" => array( "Default Test Mode State", "string", "false", "The default state of test mode of the uploader shortcode. It can be 'true' or 'false'." ),
306
- "WFU_DEBUGMODE" => array( "Default Debug Mode State", "string", "false", "The default state of debug mode of the uploader shortcode. It can be 'true' or 'false'." ),
307
- "WFU_WIDTHS" => array( "Default Element Widths", "string", "", "The default widths of the elements of the uploader shortcode. It is a comma-separated list of element widths." ),
308
- "WFU_HEIGHTS" => array( "Default Element Heights", "string", "", "The default heights of the elements of the uploader shortcode. It is a comma-separated list of element heights." ),
309
- "WFU_PLACEMENTS" => array( "Default Element Placements", "string", "title/filename+selectbutton+uploadbutton/subfolders"."/userdata"."/message", "The default placements of the elements of the uploader shortcode. Check plugin's support page for syntax." ),
310
- "WFU_USERDATA" => array( "Default User Fields State", "string", "false", "The default state of custom user fields of the uploader shortcode. It can be 'true' or 'false'." ),
311
- "WFU_MEDIALINK" => array( "Default Add to Media State", "string", "false", "The default state for adding files to Media of the uploader shortcode. It can be 'true' or 'false'." ),
312
- "WFU_POSTLINK" => array( "Default Attachment to Post State", "string", "false", "The default state for attaching files to current post of the uploader shortcode. It can be 'true' or 'false'." ),
313
- "WFU_WEBCAM" => array( "Default Webcam State", "string", "false", "The default state for webcam capture. It can be 'true' or 'false'." ),
314
- "WFU_AUDIOCAPTURE" => array( "Default Capture Audio State", "string", "false", "The default state of audio capture. If it is set to 'true' then audio will be captured, together with video from the webcam. It can be 'true' or 'false'." ),
315
- "WFU_WEBCAMMODE" => array( "Default Webcam Mode", "string", "capture video", "The default webcam capture mode. It can be 'capture video', 'take photos' or 'both'." ),
316
- "WFU_VIDEOWIDTH" => array( "Default Video Width", "string", "", "The default preferable video width for webcam capture. It can be any positive integer in pixels." ),
317
- "WFU_VIDEOHEIGHT" => array( "Default Video Height", "string", "", "The default preferable video height for webcam capture. It can be any positive integer in pixels." ),
318
- "WFU_VIDEOASPECTRATIO" => array( "Default Video Aspect Ratio", "string", "", "The default preferable video aspect ratio for webcam video capture. It can be any positive value." ),
319
- "WFU_VIDEOFRAMERATE" => array( "Default Video Frame Rate", "string", "", "The default preferable video frame rate for webcam video capture. It can be any positive value in frames/sec." ),
320
- "WFU_CAMERAFACING" => array( "Default Camera Facing Mode", "string", "any", "The default preferable camera to be used for video/screenshot capture. It can be 'any', 'front' or 'back'." ),
321
- "WFU_MAXRECORDTIME" => array( "Default Maximum Record Time", "string", "10", "The default maximum video recording time in seconds. The default value is 10 seconds." ),
322
- "WFU_ASKCONSENT" => array( "Default Ask Consent State", "string", "false", "The default state of personal data consent request. The default value is false." ),
323
- "WFU_PERSONALDATATYPES" => array( "Default Personal Data Types", "string", "userdata", "The default personal data types. The default value is 'userdata'." ),
324
- "WFU_NOTREMEMBERCONSENT" => array( "Default Do Not Remember Consent Answer State", "string", "false", "The default state about remembering or not user's answer on consent question. The default value is true." ),
325
- "WFU_CONSENTREJECTUPLOAD" => array( "Default Reject Upload on Consent Denial State", "string", "false", "The default state of continuing or rejecting the upload depending on consent answer. The default value is true." ),
326
- "WFU_CONSENTFORMAT" => array( "Default Consent Format", "string", "radio", "The default format of consent question. The default value is 'checkbox'." ),
327
- "WFU_CONSENTPRESELECT" => array( "Default Consent Preselect State", "string", "none", "The default preselect state of consent question when checkbox format is active. The default value is false." )
328
- );
329
- //other plugin values
330
- $GLOBALS["WFU_GLOBALS"] += array(
331
- "WFU_DEBUG" => array( "Plugin Debug Mode", "string", "OFF", "If DEBUG mode is activated then advanced hook of plugin's function can be performed. This option may make the plugin slower, so use it very carefully. It can be 'OFF' or 'ON'." ),
332
- "WFU_RESTRICT_FRONTEND_LOADING" => array( "Restrict Front-End Loading", "string", "false", "It defines whether the plugin will load on all pages or specific ones. If it is 'false' then it will load on all pages. To restrict loading only on specific pages set a comma-separated list of page or post IDs." ),
333
- "WFU_UPLOADPROGRESS_MODE" => array( "Upload Progress Mode", "string", "incremental", "Defines how the upload progress is calculated. It can be 'incremental' or 'absolute'. Default value is 'incremental'." ),
334
- "WFU_DOS_ATTACKS_CHECK" => array( "Check for Denial-Of-Service Attacks", "string", "true", "If it is true then then plugin will check if the number of files uploaded within a specific amount of time exceeds the limit, thus protecting from DOS attacks. It can be 'true' or 'false'." ),
335
- "WFU_DOS_ATTACKS_FILE_LIMIT" => array( "Denial-Of-Service File Limit", "integer", 10000, "Defines the maximum number of files that are allowed to be uploaded within a specific amount of time. It can be any positive integer." ),
336
- "WFU_DOS_ATTACKS_TIME_INTERVAL" => array( "Denial-Of-Service Time Interval", "integer", 3600, "Defines the time interval for DOS attacks check. The time interval is given in seconds." ),
337
- "WFU_DOS_ATTACKS_ADMIN_EMAIL_FREQUENCY" => array( "Denial-Of-Service Admin Email Frequency", "integer", 3600, "Defines how frequently an email will be sent to administrator notifying for Denial-Of-Service attacks. The time interval is given in seconds." ),
338
- "WFU_SANITIZE_FILENAME_MODE" => array( "Filename Sanitization Mode", "string", "strict", "The sanitization mode for filenames. It can be 'strict' or 'loose'." ),
339
- "WFU_SANITIZE_FILENAME_DOTS" => array( "Sanitize Filename Dots", "string", "true", "Convert dot symbols (.) in filename into dashes, in order to avoid double extensions. It can be 'true' or 'false'." ),
340
- "WFU_WILDCARD_ASTERISK_MODE" => array( "Wildcard Asterisk Mode", "string", "strict", "The mode of wildcard pattern asterisk symbol. If it is strict, then the asterisk will not match dot (.) characters. It can be 'strict' or 'loose'." ),
341
- "WFU_CHECKPHPTAGS_FILETYPES" => array( "PHP Tag Checking File Types", "string", "commonimages", "The file types for which the plugin will check their contents for PHP tags. It can be 'all', 'commonimages' or 'none'." ),
342
- "WFU_PHP_ARRAY_MAXLEN" => array( "Max PHP Array Length", "string", "10000", "The maximum allowable number of items of a PHP array." ),
343
- "WFU_ADMINBROWSER_TABLE_MAXROWS" => array( "Admin Browser Rows Per Page", "integer", 25, "The number of rows per page of the admin browser. A value equal to zero or less denotes no pagination." ),
344
- "WFU_HISTORYLOG_TABLE_MAXROWS" => array( "History Log Table Rows Per Page", "integer", 25, "The number of rows per page of the History Log table." ),
345
- "WFU_UPLOADEDFILES_TABLE_MAXROWS" => array( "Uploaded Files Table Rows Per Page", "integer", 25, "The number of rows per page of the Uploaded Files table." ),
346
- "WFU_ALTERNATIVE_RANDOMIZER" => array( "Use Alternative Randomizer", "string", "false", "On fast web servers the plugin's generator of random strings may not work properly causing various problems. If it is set to true, an alternative randomizer method is employed that works for fast web servers. It can be 'true' or 'false'." ),
347
- "WFU_FORCE_NOTIFICATIONS" => array( "Force Email Notifications", "string", "false", "Send email notifications (if they are activated) even if no file has been uploaded. It can be 'true' or 'false'." ),
348
- "WFU_UPDATE_MEDIA_ON_DELETE" => array( "Update Media on Delete", "string", "true", "When an uploaded file is deleted then delete also the corresponding Media Library item if exists. It can be 'true' or 'false'." ),
349
- "WFU_DASHBOARD_PROTECTED" => array( "Dashboard Is Protected", "string", "false", "If /wp-admin folder is password protected then this variable should be set to 'true' so that internal operations of the plugin can work. The username and password should also be set." ),
350
- "WFU_DASHBOARD_USERNAME" => array( "Protected Dashboard Username", "string", "", "Username entry for accessing protected /wp-admin folder." ),
351
- "WFU_DASHBOARD_PASSWORD" => array( "Protected Dashboard Password", "string", "", "Password entry for accessing protected /wp-admin folder." ),
352
- "WFU_EXPORT_DATA_SEPARATOR" => array( "Export Data Separator", "string", ",", "This is the delimiter of the exported file data columns. It can be any symbol. Default value is comma (,)." ),
353
- "WFU_EXPORT_USERDATA_SEPARATOR" => array( "Export User Data Separator", "string", ";", "This is the delimiter of the exported user data of each file. It can be any symbol. Default value is semicolon (;)." ),
354
- "WFU_DISABLE_VERSION_CHECK" => array( "Disable Version Check", "string", "false", "If it is set to 'true' then the plugin will not check if there are any new versions available. This is a temporary solution to problems having some users accessing Iptanus Services server causing the plugin to stall. It can be 'true' or 'false'." ),
355
- "WFU_RELAX_CURL_VERIFY_HOST" => array( "Relax cURL Host Verification", "string", "false", "If it is set to 'true' then CURLOPT_SSL_VERIFYHOST will be disabled when executing a cURL POST request. This is required in some cases so that the plugin can reach https://services2.iptanus.com, because on some servers it fails with a file_get_contents warning. It can be 'true' or 'false'." ),
356
- "WFU_USE_ALT_IPTANUS_SERVER" => array( "Use Alternative Iptanus Server", "string", "false", "If it is set to 'true' then the alternative Iptanus server will be used. This is a work-around in some cases where the website cannot reach https://services2.iptanus.com. It can be 'true' or 'false'." ),
357
- "WFU_ALT_IPTANUS_SERVER" => array( "Alternative Iptanus Server", "string", "https://iptanusservices.appspot.com", "If it is set then this is the URL of the alternative Iptanus server." ),
358
- "WFU_ALT_VERSION_SERVER" => array( "Alternative Version Server", "string", "https://iptanusservices.appspot.com/g79xo30q8s", "If the alternative Iptanus server is used and this variable is not empty, then it will be used as the alternative Version Server URL." ),
359
- "WFU_MINIFY_INLINE_CSS" => array( "Minify Inline CSS Code", "string", "true", "Defines whether the inline CSS code will be minified. It can be 'true' or 'false'." ),
360
- "WFU_MINIFY_INLINE_JS" => array( "Minify Inline JS Code", "string", "true", "Defines whether the inline Javascript code will be minified. It can be 'true' or 'false'." ),
361
- "WFU_US_SESSION_LEGACY" => array( "Session Legacy Option", "string", "true", "Defines whether the old (legacy) operation of reading and storing session data (using session_start in header) will be used. By default it is set to 'true' to maintain backward compatibility." ),
362
- "WFU_US_COOKIE_LIFE" => array( "Session Cookie Life", "integer", 48, "Defines the life of session cookie, in hours." ),
363
- "WFU_US_DBOPTION_BASE" => array( "DB Option User State Base", "string", "cookies", "Defines how DB option defines the unique user state key. It can take the values 'session' or 'cookies'." ),
364
- "WFU_US_DBOPTION_CHECK" => array( "DB Option User State Check Interval", "integer", 7200, "Defines how often (in seconds) the plugin will update user state list, when user state is saved in DB option table." ),
365
- "WFU_US_DBOPTION_LIFE" => array( "DB Option User State Life", "integer", 1800, "Defines the maximum time of inactivity of a user state, when user state is saved in DB option table." ),
366
- "WFU_US_HANDLER_CHANGED" => array( "User State Handler Changed", "string", "false", "Defines whether the plugin changed automatically the user state handler during installation." ),
367
- "WFU_US_DBOPTION_USEOLD" => array( "Use Old DB Option Handler", "string", "false", "Defines whether the old DBOption user state handlers will be used." ),
368
- "WFU_US_DEADLOCK_TIMEOUT" => array( "Database Deadlock Timeout", "integer", 10, "Defines for how long a deadlocked database transaction will be repeated." ),
369
- "WFU_US_LOG_DBERRORS" => array( "Log Database Errors", "string", "false", "Defines whether database errors will be logged." ),
370
- "WFU_QUEUE_ACTIVE" => array( "Enable Queue Functionality", "string", "true", "Defines whether queue operation is active." ),
371
- "WFU_QUEUE_THREAD_TIMEOUT" => array( "Queue Thread Timeout", "integer", 5, "Defines for how long, in seconds, a queue will wait for a thread to finish before aborting the operation." ),
372
- "WFU_QUEUE_LOOP_DELAY" => array( "Queue Loop Delay", "integer", 100, "Defines the time, in milliseconds, a wait loop will sleep before continuing." ),
373
- "WFU_PD_VISIBLE_OPLEVELS" => array( "Personal Data Visible Operation Levels", "integer", 3, "Defines how deep administrators can go into personal data operation details. A value of -1 denotes that there is no limit." ),
374
- "WFU_PD_VISIBLE_PERLEVELS" => array( "Personal Data Visible Permission Levels", "integer", 2, "Defines how deep administrators can go into personal data permission details. A value of -1 denotes that there is no limit." ),
375
- "WFU_PD_VISIBLE_LOGLEVELS" => array( "Personal Data Visible Log Action Levels", "integer", 2, "Defines how deep administrators can go into personal data log action details. A value of -1 denotes that there is no limit." ),
376
- "WFU_UPLOADEDFILES_MENU" => array( "Uploaded Files Menu State", "string", "true", "Defines whether the Uploaded Files Dashboard menu item will be shown or not. It can be 'true' or 'false'." ),
377
- "WFU_UPLOADEDFILES_DEFACTION" => array( "Uploaded Files Default Action", "string", "adminbrowser", "Defines the default action that will be executed when a file link is pressed in Uploaded Files page. It can be 'details', 'adminbrowser', 'historylog', 'link', 'download' and 'none'." ),
378
- "WFU_UPLOADEDFILES_COLUMNS" => array( "Uploaded Files Columns", "string", "#, file, upload_date, user, properties, remarks, actions", "Defines the visible columns of the Uploaded Files list as well as their order. It is noted that 'File' column is always visible and it is the second column if '#' column is visible, or the first one if '#' column is hidden." ),
379
- "WFU_UPLOADEDFILES_ACTIONS" => array( "Uploaded Files Actions", "string", "details, media, adminbrowser, historylog, link, download, remotelinks", "Defines the allowable actions and their order for each file in Uploaded Files list. It is noted that the actions shown for each file depend on its properties." ),
380
- "WFU_UPLOADEDFILES_HIDEINVALID" => array( "Hide Invalid Uploaded Files", "string", "false", "Defines whether all uploaded file records will be shown in Uploaded File menu or only the valid ones. Invalid are the records who are obsolete or their files do not exist anymore." ),
381
- "WFU_UPLOADEDFILES_RESET_TIME" => array( "Uploaded Files Reset Time", "integer", 5, "Defines the interval in seconds before the unread uploaded files can be marked as read. A value of -1 denotes that there is no interval." ),
382
- "WFU_UPLOADEDFILES_BARMENU" => array( "Uploaded Files Toolbar Menu State", "string", "true", "Defines whether the Uploaded Files Toolbar (Admin Bar) menu item will be shown or not. It can be 'true' or 'false'." ),
383
- "WFU_UPLOADEDFILES_BARAUTOHIDE" => array( "Uploaded Files Auto-Hide on Toolbar", "string", "false", "Defines whether the Uploaded Files Toolbar (Admin Bar) menu item will be hidden when there are no new uploads. It can be 'true' or 'false'." ),
384
- "WFU_SHORTCODECOMPOSER_NOADMIN" => array( "Show Shortcode Composer to Non-Admins", "string", "true", "Defines whether the shortcode composer will be visible to non-admin users who can edit posts or pages. It can be 'true' or 'false'." ),
385
- "WFU_FILEOPERATION_IGNOREFTP" => array( "Ignore FTP Path in File Operations", "string", "false", "Defines whether file functions, such as file_exists(), stat() etc. will be ignored for FTP paths. It can be 'true' or 'false'." ),
386
- "WFU_FTPFILEEXISTS_DEFVALUE" => array( "Default Value of File Exists for FTP Paths", "string", "true", "Defines the default value that will be returned when file_exists() function is executed on an FTP path. It can be '*true', '*false', '*calc', 'true' or 'false'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
387
- "WFU_FTPSTAT_DEFVALUE" => array( "Default Value of Stat for FTP Paths", "string", "empty", "Defines the default value that will be returned when stat() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
388
- "WFU_FTPFILESIZE_DEFVALUE" => array( "Default Value of Filesize for FTP Paths", "string", "empty", "Defines the default value that will be returned when filesize() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
389
- "WFU_FTPFOPEN_DEFVALUE" => array( "Default Value of Fopen for FTP Paths", "string", "empty", "Defines the default value that will be returned when fopen() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
390
- "WFU_FTPFILEGETCONTENTS_DEFVALUE" => array( "Default Value of File Get Contents for FTP Paths", "string", "empty", "Defines the default value that will be returned when file_get_contents() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
391
- "WFU_FTPMD5FILE_DEFVALUE" => array( "Default Value of MD5 File for FTP Paths", "string", "empty", "Defines the default value that will be returned when md5_file() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
392
- "WFU_FTPUNLINK_DEFVALUE" => array( "Default Value of Unlink for FTP Paths", "string", "empty", "Defines the default value that will be returned when unlink() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
393
- "WFU_FILEOPERATION_IGNORESFTP" => array( "Ignore SFTP Path in File Operations", "string", "false", "Defines whether file functions, such as file_exists(), stat() etc. will be ignored for SFTP paths. It can be 'true' or 'false'." ),
394
- "WFU_SFTPFILEEXISTS_DEFVALUE" => array( "Default Value of File Exists for SFTP Paths", "string", "true", "Defines the default value that will be returned when file_exists() function is executed on an SFTP path. It can be '*true', '*false', '*calc', 'true' or 'false'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
395
- "WFU_SFTPSTAT_DEFVALUE" => array( "Default Value of Stat for SFTP Paths", "string", "empty", "Defines the default value that will be returned when stat() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
396
- "WFU_SFTPFILESIZE_DEFVALUE" => array( "Default Value of Filesize for SFTP Paths", "string", "empty", "Defines the default value that will be returned when filesize() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
397
- "WFU_SFTPFOPEN_DEFVALUE" => array( "Default Value of Fopen for SFTP Paths", "string", "empty", "Defines the default value that will be returned when fopen() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
398
- "WFU_SFTPFILEGETCONTENTS_DEFVALUE" => array( "Default Value of File Get Contents for SFTP Paths", "string", "empty", "Defines the default value that will be returned when file_get_contents() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
399
- "WFU_SFTPMD5FILE_DEFVALUE" => array( "Default Value of MD5 File for SFTP Paths", "string", "empty", "Defines the default value that will be returned when md5_file() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
400
- "WFU_SFTPUNLINK_DEFVALUE" => array( "Default Value of Unlink for SFTP Paths", "string", "empty", "Defines the default value that will be returned when unlink() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
401
- );
402
- //color definitions
403
- $GLOBALS["WFU_GLOBALS"] += array(
404
- "WFU_TESTMESSAGECOLORS" => array( "Colors for Message in Test Mode", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message in Test mode of the uploader shortcode." ),
405
- "WFU_DEFAULTMESSAGECOLORS" => array( "Defaults Message Colors", "string", "#666666,#EEEEEE,#333333", "The default color triplet (text, background and border colors) of message of the uploader shortcode." ),
406
- "WFU_HEADERMESSAGECOLORS_STATE0" => array( "State 0 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 0 (upload in progress with no messages) of the uploader shortcode." ),
407
- "WFU_HEADERMESSAGECOLORS_STATE1" => array( "State 1 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 1 (upload in progress with messages) of the uploader shortcode." ),
408
- "WFU_HEADERMESSAGECOLORS_STATE2" => array( "State 2 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 2 (upload in progress with some files not uploaded) of the uploader shortcode." ),
409
- "WFU_HEADERMESSAGECOLORS_STATE3" => array( "State 3 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 3 (upload in progress with no files uploaded so far) of the uploader shortcode." ),
410
- "WFU_HEADERMESSAGECOLORS_STATE4" => array( "State 4 Message Colors", "string", "#006600,#EEFFEE,#006666", "The color triplet (text, background and border colors) of message of upload state 4 (all files uploaded) of the uploader shortcode." ),
411
- "WFU_HEADERMESSAGECOLORS_STATE5" => array( "State 5 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 5 (all files uploaded with messages) of the uploader shortcode." ),
412
- "WFU_HEADERMESSAGECOLORS_STATE6" => array( "State 6 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 6 (some files not uploaded) of the uploader shortcode." ),
413
- "WFU_HEADERMESSAGECOLORS_STATE7" => array( "State 7 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 7 (no files uploaded) of the uploader shortcode." ),
414
- "WFU_HEADERMESSAGECOLORS_STATE8" => array( "State 8 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 8 (there are no files to upload) of the uploader shortcode." ),
415
- "WFU_HEADERMESSAGECOLORS_STATE9" => array( "State 9 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 9 (test state) of the uploader shortcode." ),
416
- "WFU_HEADERMESSAGECOLORS_STATE10" => array( "State 10 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 10 (JSON parse error) of the uploader shortcode." ),
417
- "WFU_HEADERMESSAGECOLORS_STATE11" => array( "State 11 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 11 (redirecting) of the uploader shortcode." ),
418
- "WFU_HEADERMESSAGECOLORS_STATE12" => array( "State 12 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 12 (upload failed) of the uploader shortcode." ),
419
- "WFU_HEADERMESSAGECOLORS_STATE13" => array( "State 13 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 13 (sending data) of the uploader shortcode." ),
420
- "WFU_HEADERMESSAGECOLORS_STATE14" => array( "State 14 Message Colors", "string", "#006600,#EEFFEE,#006666", "The color triplet (text, background and border colors) of message of upload state 14 (data submit succeeded) of the uploader shortcode." ),
421
- "WFU_HEADERMESSAGECOLORS_STATE15" => array( "State 15 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 15 (data submit failed) of the uploader shortcode." ),
422
- "WFU_HEADERMESSAGECOLORS_STATE16" => array( "State 16 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 16 (cancelling upload) of the uploader shortcode." ),
423
- "WFU_HEADERMESSAGECOLORS_STATE17" => array( "State 17 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 17 (upload cancelled) of the uploader shortcode." ),
424
- "WFU_HEADERMESSAGECOLORS_STATE18" => array( "State 18 Message Colors", "string", "#006600,#EEFFEE,#006666", "The color triplet (text, background and border colors) of message of upload state 18 (upload succeeded) of the uploader shortcode." ),
425
- "WFU_HEADERMESSAGECOLORS_STATE19" => array( "State 19 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 19 (upload completed but no files were saved due to personal data policy) of the uploader shortcode." )
426
- );
427
- //insert saved values to array
428
- $envars = get_option("wfu_environment_variables", array());
429
- foreach ( $GLOBALS["WFU_GLOBALS"] as $ind => $envar ) {
430
- if ( isset($envars[$ind]) ) {
431
- if ( $envar[1] == "integer" ) $saved = (int)$envars[$ind];
432
- else $saved = (string)$envars[$ind];
433
- }
434
- else $saved = $envar[2];
435
- array_splice($GLOBALS["WFU_GLOBALS"][$ind], 3, 0, array( $saved ));
436
- //add visibility
437
- $GLOBALS["WFU_GLOBALS"][$ind][5] = true;
438
- }
439
-
440
- //hide unwanted environment variables
441
- $GLOBALS["WFU_GLOBALS"]["WFU_RELAX_CURL_VERIFY_HOST"][5] = false;
442
- $GLOBALS["WFU_GLOBALS"]["WFU_USE_ALT_IPTANUS_SERVER"][5] = false;
443
-
444
- /************** Constant Values ***************/
445
- //other plugin values
446
- DEFINE("WFU_SUCCESSMESSAGECOLOR", "green");
447
- DEFINE("WFU_MAX_TIME_LIMIT", ini_get("max_input_time"));
448
- DEFINE("WFU_RESPONSE_URL", WPFILEUPLOAD_DIR."wfu_response.php");
449
- DEFINE("WFU_SERVICES_SERVER_URL", 'https://services2.iptanus.com');
450
- DEFINE("WFU_VERSION_SERVER_URL", WFU_SERVICES_SERVER_URL.'/wp-admin/admin-ajax.php');
451
- DEFINE("WFU_VERSION_HASH", '9npWpXMhAQ5e6AGJ5zqbaPxLk9ePD3eSu3WKeN9p89E9wmgL2PHtrqXPzBVpStzh');
452
- DEFINE("WFU_DOWNLOADER_URL", WPFILEUPLOAD_DIR."wfu_file_downloader.php");
453
- DEFINE("WFU_IPTANUS_SERVER_UNREACHABLE_ARTICLE", 'https://www.iptanus.com/iptanus-services-server-unreachable-error-wfu-plugin/');
454
- //alternative insecure server
455
- DEFINE("WFU_SERVICES_SERVER_ALT_URL", 'http://services.iptanus.com');
456
- DEFINE("WFU_VERSION_SERVER_ALT_URL", WFU_SERVICES_SERVER_ALT_URL.'/wp-admin/admin-ajax.php');
457
- DEFINE("WFU_PRO_VERSION_URL", 'https://www.iptanus.com/product/wordpress-file-upload-pro/');
458
- //define images
459
- DEFINE("WFU_IMAGE_ADMIN_HELP", WPFILEUPLOAD_DIR.'images/help_16.png');
460
- DEFINE("WFU_IMAGE_ADMIN_RESTOREDEFAULT", WPFILEUPLOAD_DIR.'images/restore_16.png');
461
- DEFINE("WFU_IMAGE_ADMIN_USERDATA_ADD", WPFILEUPLOAD_DIR.'images/add_12.png');
462
- DEFINE("WFU_IMAGE_ADMIN_USERDATA_REMOVE", WPFILEUPLOAD_DIR.'images/remove_12.png');
463
- DEFINE("WFU_IMAGE_ADMIN_USERDATA_UP", WPFILEUPLOAD_DIR.'images/up_12.png');
464
- DEFINE("WFU_IMAGE_ADMIN_USERDATA_DOWN", WPFILEUPLOAD_DIR.'images/down_12.png');
465
- DEFINE("WFU_IMAGE_ADMIN_SUBFOLDER_BROWSE", WPFILEUPLOAD_DIR.'images/tree_16.gif');
466
- DEFINE("WFU_IMAGE_ADMIN_SUBFOLDER_OK", WPFILEUPLOAD_DIR.'images/ok_12.gif');
467
- DEFINE("WFU_IMAGE_ADMIN_SUBFOLDER_CANCEL", WPFILEUPLOAD_DIR.'images/cancel_12.gif');
468
- DEFINE("WFU_IMAGE_ADMIN_SUBFOLDER_LOADING", WPFILEUPLOAD_DIR.'images/refresh_16.gif');
469
- DEFINE("WFU_IMAGE_SIMPLE_PROGBAR", WPFILEUPLOAD_DIR.'images/progbar.gif');
470
- DEFINE("WFU_IMAGE_OVERLAY_EDITOR", WPFILEUPLOAD_DIR.'images/pencil.svg');
471
- DEFINE("WFU_IMAGE_OVERLAY_LOADING", WPFILEUPLOAD_DIR.'images/loading_icon.gif');
472
- DEFINE("WFU_IMAGE_FILE_CANCEL", WPFILEUPLOAD_DIR.'images/cancel_16.png');
473
- DEFINE("WFU_IMAGE_MEDIA_BUTTONS", WPFILEUPLOAD_DIR.'images/open-iconic.svg');
474
- DEFINE("WFU_IMAGE_VERSION_COMPARISON", WPFILEUPLOAD_DIR.'images/Version Comparison.png');
475
-
476
- /**
477
- * Front-End Constants Initialization
478
- *
479
- * This function initializes all constants that need to be passed to the front-
480
- * end scripts of the upload form.
481
- *
482
- * @since 2.1.2
483
- */
484
- function wfu_set_javascript_constants() {
485
- $consts = array(
486
- "notify_testmode" => WFU_NOTIFY_TESTMODE,
487
- "nofilemessage" => WFU_ERROR_UPLOAD_NOFILESELECTED,
488
- "enable_popups" => WFU_ERROR_ENABLE_POPUPS,
489
- "remoteserver_noresult" => WFU_ERROR_REMOTESERVER_NORESULT,
490
- "message_header" => WFU_ERRORMESSAGE,
491
- "message_failed" => WFU_ERROR_UPLOAD_FAILED_WHILE,
492
- "message_cancelled" => WFU_ERROR_UPLOAD_CANCELLED,
493
- "message_unknown" => WFU_ERROR_UNKNOWN,
494
- "adminmessage_unknown" => WFU_FAILMESSAGE_DETAILS,
495
- "message_timelimit" => WFU_ERROR_FILE_PHP_TIME,
496
- "message_admin_timelimit" => WFU_ERROR_ADMIN_FILE_PHP_TIME,
497
- "cancel_upload_prompt" => WFU_CANCEL_UPLOAD_PROMPT,
498
- "file_cancelled" => WFU_ERROR_FILE_CANCELLED,
499
- "jsonparse_filemessage" => WFU_ERROR_JSONPARSE_FILEMESSAGE,
500
- "jsonparse_message" => WFU_ERROR_JSONPARSE_MESSAGE,
501
- "jsonparse_adminmessage" => WFU_ERROR_JSONPARSE_ADMINMESSAGE,
502
- "jsonparse_headermessage" => WFU_ERROR_JSONPARSE_HEADERMESSAGE,
503
- "jsonparse_headeradminmessage" => WFU_ERROR_JSONPARSE_HEADERADMINMESSAGE,
504
- "same_pluginid" => WFU_ERROR_SAME_PLUGINID,
505
- "webcam_video_notsupported" => WFU_ERROR_WEBCAM_VIDEO_NOTSUPPORTED,
506
- "webcam_video_nothingrecorded" => WFU_ERROR_WEBCAM_VIDEO_NOTHINGRECORDED,
507
- "default_colors" => WFU_VAR("WFU_DEFAULTMESSAGECOLORS"),
508
- "fail_colors" => WFU_VAR("WFU_FAILMESSAGECOLORS"),
509
- "max_time_limit" => WFU_MAX_TIME_LIMIT,
510
- "response_url" => WFU_RESPONSE_URL,
511
- "ajax_url" => wfu_ajaxurl(),
512
- "wfu_pageexit_prompt" => WFU_PAGEEXIT_PROMPT,
513
- "wfu_subdir_typedir" => WFU_SUBDIR_TYPEDIR,
514
- "wfu_uploadprogress_mode" => WFU_VAR("WFU_UPLOADPROGRESS_MODE"),
515
- "wfu_consent_notcompleted" => WFU_WARNING_CONSENT_NOTCOMPLETED
516
- );
517
- $consts_txt = "";
518
- foreach ( $consts as $key => $val )
519
- $consts_txt .= ( $consts_txt == "" ? "" : ";" ).wfu_plugin_encode_string($key).":".wfu_plugin_encode_string($val);
520
-
521
- return $consts_txt;
 
 
 
 
 
 
 
 
522
  }
1
+ <?php
2
+
3
+ /**
4
+ * Constants and Strings of Plugin
5
+ *
6
+ * This file initializes all constants and translatable strings of the plugin.
7
+ *
8
+ * @link /lib/wfu_constants.php
9
+ *
10
+ * @package WordPress File Upload Plugin
11
+ * @subpackage Core Components
12
+ * @since 2.1.2
13
+ */
14
+
15
+ $siteurl = site_url();
16
+
17
+ /**
18
+ * Translatable Strings Initialization.
19
+ *
20
+ * This function initializes all translatable strings of the plugin.
21
+ *
22
+ * @since 4.7.0
23
+ */
24
+ function wfu_initialize_i18n_strings() {
25
+ if ( defined("WFU_I18_LOADED") ) return;
26
+ DEFINE("WFU_I18_LOADED", 1);
27
+ //plugin default values
28
+ DEFINE("WFU_UPLOADTITLE", __('Upload files', 'wp-file-upload'));
29
+ DEFINE("WFU_SELECTBUTTON", __('Select File', 'wp-file-upload'));
30
+ DEFINE("WFU_UPLOADBUTTON", __('Upload File', 'wp-file-upload'));
31
+ DEFINE("WFU_NOTIFYSUBJECT", __('File Upload Notification', 'wp-file-upload'));
32
+ DEFINE("WFU_NOTIFYMESSAGE", __("Dear Recipient,%n%%n% This is an automatic delivery message to notify you that a new file has been uploaded.%n%%n%Best Regards", 'wp-file-upload'));
33
+ DEFINE("WFU_SUCCESSMESSAGE", __('File %filename% uploaded successfully', 'wp-file-upload'));
34
+ DEFINE("WFU_WARNINGMESSAGE", __('File %filename% uploaded successfully but with warnings', 'wp-file-upload'));
35
+ DEFINE("WFU_ERRORMESSAGE", __('File %filename% not uploaded', 'wp-file-upload'));
36
+ DEFINE("WFU_WAITMESSAGE", __('File %filename% is being uploaded', 'wp-file-upload'));
37
+ DEFINE("WFU_USERDATALABEL", __('Your message', 'wp-file-upload')."|t:text|s:left|r:0|a:0|p:inline|d:");
38
+ DEFINE("WFU_CAPTCHAPROMPT", __('Please fill in the above words: ', 'wp-file-upload'));
39
+ DEFINE("WFU_UPLOADMEDIABUTTON", __('Upload Media', 'wp-file-upload'));
40
+ DEFINE("WFU_VIDEONAME", __('videostream', 'wp-file-upload'));
41
+ DEFINE("WFU_IMAGENAME", __('screenshot', 'wp-file-upload'));
42
+ DEFINE("WFU_CONSENTQUESTION", __('By activating this option I agree to let the website keep my personal data', 'wp-file-upload'));
43
+ DEFINE("WFU_CONSENTREJECTMESSAGE", __('You have denied to let the website keep your personal data. Upload cannot continue!', 'wp-file-upload'));
44
+ DEFINE("WFU_CONSENTYES", __('Yes', 'wp-file-upload'));
45
+ DEFINE("WFU_CONSENTNO", __('No', 'wp-file-upload'));
46
+ //browser default values
47
+ DEFINE("WFU_FILETITLE", __('File', 'wp-file-upload'));
48
+ DEFINE("WFU_DATETITLE", __('Date', 'wp-file-upload'));
49
+ DEFINE("WFU_SIZETITLE", __('Size', 'wp-file-upload'));
50
+ DEFINE("WFU_USERTITLE", __('User', 'wp-file-upload'));
51
+ DEFINE("WFU_POSTTITLE", __('Page', 'wp-file-upload'));
52
+ DEFINE("WFU_FIELDSTITLE", __('User Fields', 'wp-file-upload'));
53
+ DEFINE("WFU_DOWNLOADLABEL", __('Download', 'wp-file-upload'));
54
+ DEFINE("WFU_DOWNLOADTITLE", __('Download this file', 'wp-file-upload'));
55
+ DEFINE("WFU_DELETELABEL", __('Delete', 'wp-file-upload'));
56
+ DEFINE("WFU_DELETETITLE", __('Delete this file', 'wp-file-upload'));
57
+ DEFINE("WFU_REMOVEREMOTELABEL", __('Remove Remote', 'wp-file-upload'));
58
+ DEFINE("WFU_REMOVEREMOTETITLE", __('Remove this remote file', 'wp-file-upload'));
59
+ DEFINE("WFU_SORTTITLE", __('Sort list based on this column', 'wp-file-upload'));
60
+ DEFINE("WFU_GUESTTITLE", __('guest', 'wp-file-upload'));
61
+ DEFINE("WFU_UNKNOWNTITLE", __('unknown', 'wp-file-upload'));
62
+ //error messages
63
+ DEFINE("WFU_ERROR_ADMIN_FTPDIR_RESOLVE", __("Error. Could not resolve ftp target filedir. Check the domain in 'ftpinfo' attribute.", "wp-file-upload"));
64
+ DEFINE("WFU_ERROR_ADMIN_FTPINFO_INVALID", __("Error. Invalid ftp information. Check 'ftpinfo' attribute.", "wp-file-upload"));
65
+ DEFINE("WFU_ERROR_ADMIN_FTPINFO_EXTRACT", __("Error. Could not extract ftp information from 'ftpinfo' attribute. Check its syntax.", "wp-file-upload"));
66
+ DEFINE("WFU_ERROR_ADMIN_FTPFILE_RESOLVE", __("Error. Could not resolve ftp target filename. Check the domain in 'ftpinfo' attribute.", "wp-file-upload"));
67
+ DEFINE("WFU_ERROR_ADMIN_FTPSOURCE_FAIL", __("Error. Could not open source file for ftp upload. Check if file is accessible.", "wp-file-upload"));
68
+ DEFINE("WFU_ERROR_ADMIN_FTPTRANSFER_FAIL", __("Error. Could not send data to ftp target file.", "wp-file-upload"));
69
+ DEFINE("WFU_ERROR_ADMIN_FTPHOST_FAIL", __("Error. Could not connect to ftp host. Check the domain in 'ftpinfo' attribute.", "wp-file-upload"));
70
+ DEFINE("WFU_ERROR_ADMIN_FTPLOGIN_FAIL", __("Error. Could not authenticate to ftp host. Check username and password in 'ftpinfo' attribute.", "wp-file-upload"));
71
+ DEFINE("WFU_ERROR_ADMIN_SFTPINIT_FAIL", __("Error. Could not initialize sftp subsystem. Please check if the server supports sftp.", "wp-file-upload"));
72
+ DEFINE("WFU_ERROR_ADMIN_SFTP_UNSUPPORTED", __("Error. The web server does not support sftp.", "wp-file-upload"));
73
+ DEFINE("WFU_ERROR_ADMIN_FILE_PHP_SIZE", __("Error. The upload size limit of PHP directive upload_max_filesize is preventing the upload of big files.\nPHP directive upload_max_filesize limit is: ".ini_get("upload_max_filesize").".\nTo increase the limit change the value of the directive from php.ini.\nIf you don't have access to php.ini, then try adding the following line to your .htaccess file:\n\nphp_value upload_max_filesize 10M\n\n(adjust the size according to your needs)\n\nThe file .htaccess is found in your website root directory (where index.php is found).\nIf your don't have this file, then create it.\nIf this does not work either, then contact your domain provider.", "wp-file-upload"));
74
+ DEFINE("WFU_ERROR_ADMIN_FILE_PHP_TIME", __("The upload time limit of PHP directive max_input_time is preventing the upload of big files.\nPHP directive max_input_time limit is: ".ini_get("max_input_time")." seconds.\nTo increase the limit change the value of the directive from php.ini.\nIf you don't have access to php.ini, then add the following line to your .htaccess file:\n\nphp_value max_input_time 500\n\n(adjust the time according to your needs)\n\nThe file .htaccess is found in your website root directory (where index.php is found).\nIf your don't have this file, then create it.\nIf this does not work either, then contact your domain provider.", "wp-file-upload"));
75
+ DEFINE("WFU_ERROR_ADMIN_DIR_PERMISSION", __("Error. Permission denied to write to target folder.\nCheck and correct read/write permissions of target folder.", "wp-file-upload"));
76
+ DEFINE("WFU_ERROR_ADMIN_FILE_WRONGEXT", __("Error. This file was rejected because its extension is not correct. Its proper filename is: ", "wp-file-upload"));
77
+ DEFINE("WFU_ERROR_ADMIN_FILE_NOIMAGE", __("Error. This file was rejected because its not a valid image.", "wp-file-upload"));
78
+ DEFINE("WFU_ERROR_ADMIN_DOS_ATTACK", __("Too many files are uploaded in a short period of time. This may be a Denial-Of-Service attack, so file was rejected. Please check the upload log for suspicious behaviour.", "wp-file-upload"));
79
+ DEFINE("WFU_ERROR_DOS_ATTACK", __("File not uploaded in order to prevent overflow of the website. Please contact administrator.", "wp-file-upload"));
80
+ DEFINE("WFU_ERROR_DIR_EXIST", __("Target folder doesn't exist.", "wp-file-upload"));
81
+ DEFINE("WFU_ERROR_DIR_NOTEMP", __("Upload failed! Missing a temporary folder.", "wp-file-upload"));
82
+ DEFINE("WFU_ERROR_DIR_PERMISSION", __("Upload failed! Permission denied to write to target folder.", "wp-file-upload"));
83
+ DEFINE("WFU_ERROR_FILE_ALLOW", __("File not allowed.", "wp-file-upload"));
84
+ DEFINE("WFU_ERROR_FILE_REJECT", __("File is suspicious and was rejected.", "wp-file-upload"));
85
+ DEFINE("WFU_ERROR_FILE_PLUGIN_SIZE", __("The uploaded file exceeds the file size limit.", "wp-file-upload"));
86
+ DEFINE("WFU_ERROR_FILE_PLUGIN_2GBSIZE", __("The uploaded file exceeds 2GB and is not supported by this server.", "wp-file-upload"));
87
+ DEFINE("WFU_ERROR_FILE_PHP_SIZE", __("Upload failed! The uploaded file exceeds the file size limit of the server. Please contact the administrator.", "wp-file-upload"));
88
+ DEFINE("WFU_ERROR_FILE_PHP_TIME", __("Upload failed! The duration of the upload exceeded the time limit of the server. Please contact the administrator.", "wp-file-upload"));
89
+ DEFINE("WFU_ERROR_FILE_HTML_SIZE", __("Upload failed! The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.", "wp-file-upload"));
90
+ DEFINE("WFU_ERROR_FILE_PARTIAL", __("Upload failed! The uploaded file was only partially uploaded.", "wp-file-upload"));
91
+ DEFINE("WFU_ERROR_FILE_NOTHING", __("Upload failed! No file was uploaded.", "wp-file-upload"));
92
+ DEFINE("WFU_ERROR_FILE_WRITE", __("Upload failed! Failed to write file to disk.", "wp-file-upload"));
93
+ DEFINE("WFU_ERROR_FILE_MOVE", __("Upload failed! Error occured while moving temporary file. Please contact administrator.", "wp-file-upload"));
94
+ DEFINE("WFU_ERROR_FILE_CANCELLED", __("Upload cancelled!", "wp-file-upload"));
95
+ DEFINE("WFU_ERROR_UPLOAD_STOPPED", __("Upload failed! A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help.", "wp-file-upload"));
96
+ DEFINE("WFU_ERROR_UPLOAD_FAILED_WHILE", __("Upload failed! Error occured while attemting to upload the file.", "wp-file-upload"));
97
+ DEFINE("WFU_ERROR_UPLOAD_FAILED", __("Upload failed!", "wp-file-upload"));
98
+ DEFINE("WFU_ERROR_UPLOAD_NOFILESELECTED", __("No file!", "wp-file-upload"));
99
+ DEFINE("WFU_ERROR_UPLOAD_CANCELLED", __("Upload failed! The upload has been canceled by the user or the browser dropped the connection.", "wp-file-upload"));
100
+ DEFINE("WFU_ERROR_UNKNOWN", __("Upload failed! Unknown error.", "wp-file-upload"));
101
+ DEFINE("WFU_ERROR_CONTACT_ADMIN", __("Please contact the administrator.", "wp-file-upload"));
102
+ DEFINE("WFU_ERROR_REMOTESERVER_NORESULT", __("No result from remote server!", "wp-file-upload"));
103
+ DEFINE("WFU_ERROR_JSONPARSE_FILEMESSAGE", __(" but with warnings", "wp-file-upload"));
104
+ DEFINE("WFU_ERROR_JSONPARSE_MESSAGE", __("Warning: JSON parse error.", "wp-file-upload"));
105
+ DEFINE("WFU_ERROR_JSONPARSE_ADMINMESSAGE", __("Upload parameters of this file, passed as JSON string to the handler, could not be parsed.", "wp-file-upload"));
106
+ DEFINE("WFU_ERROR_JSONPARSE_HEADERMESSAGE", __("Warning: JSON parse error.", "wp-file-upload"));
107
+ DEFINE("WFU_ERROR_JSONPARSE_HEADERADMINMESSAGE", __("UploadStates, passed as JSON string to the handler, could not be parsed.", "wp-file-upload"));
108
+ DEFINE("WFU_ERROR_REDIRECTION_ERRORCODE0", __("Redirection to classic form functionality occurred due to unknown error.", "wp-file-upload"));
109
+ DEFINE("WFU_ERROR_REDIRECTION_ERRORCODE1", __("Redirection to classic form functionality occurred because AJAX is not supported.", "wp-file-upload"));
110
+ DEFINE("WFU_ERROR_REDIRECTION_ERRORCODE2", __("Redirection to classic form functionality occurred because HTML5 is not supported.", "wp-file-upload"));
111
+ DEFINE("WFU_ERROR_REDIRECTION_ERRORCODE3", __("Redirection to classic form functionality occurred due to JSON parse error.", "wp-file-upload"));
112
+ DEFINE("WFU_ERROR_ENABLE_POPUPS", __("Please enable popup windows from the browser's settings!", "wp-file-upload"));
113
+ DEFINE("WFU_ERROR_USERDATA_EMPTY", __("cannot be empty!", "wp-file-upload"));
114
+ DEFINE("WFU_ERROR_USERDATANUMBER_INVALID", __("number not valid!", "wp-file-upload"));
115
+ DEFINE("WFU_ERROR_USERDATAEMAIL_INVALID", __("email not valid!", "wp-file-upload"));
116
+ DEFINE("WFU_ERROR_USERDATACONFIRMEMAIL_NOMATCH", __("emails do not match!", "wp-file-upload"));
117
+ DEFINE("WFU_ERROR_USERDATACONFIRMEMAIL_NOBASE", __("no base email field in group!", "wp-file-upload"));
118
+ DEFINE("WFU_ERROR_USERDATACONFIRMPASSWORD_NOMATCH", __("passwords do not match!", "wp-file-upload"));
119
+ DEFINE("WFU_ERROR_USERDATACONFIRMPASSWORD_NOBASE", __("no base password field in group!", "wp-file-upload"));
120
+ DEFINE("WFU_ERROR_USERDATACHECKBOX_NOTCHECKED", __("checkbox unchecked!", "wp-file-upload"));
121
+ DEFINE("WFU_ERROR_USERDATARADIO_NOTSELECTED", __("no option selected!", "wp-file-upload"));
122
+ DEFINE("WFU_ERROR_USERDATALIST_NOITEMSELECTED", __("no item selected!", "wp-file-upload"));
123
+ DEFINE("WFU_ERROR_SAME_PLUGINID", __("There are more than one instances of the plugin in this page with the same id. Please change it.", "wp-file-upload"));
124
+ DEFINE("WFU_ERROR_PAGE_OBSOLETE", __("Cannot edit the shortcode because the page has been modified. Please reload the page.", "wp-file-upload"));
125
+ DEFINE("WFU_ERROR_WEBCAM_NOTSUPPORTED", __("Your browser does not support webcam capture!", "wp-file-upload"));
126
+ DEFINE("WFU_ERROR_WEBCAM_VIDEO_NOTSUPPORTED", __("Your browser does not support video recording from the webcam!", "wp-file-upload"));
127
+ DEFINE("WFU_ERROR_WEBCAM_VIDEO_NOTHINGRECORDED", __("No video was recorded!", "wp-file-upload"));
128
+ DEFINE("WFU_ERROR_CAPTCHA_OLDPHP", __("ERROR: Captcha not supported! You have an old PHP version. Upgrade your PHP or use RecaptchaV2 (no account).", "wp-file-upload"));
129
+ DEFINE("WFU_ERROR_CAPTCHA_MULTIPLE_NOTALLOWED", __("ERROR: Only one instance of RecaptchaV1 can exist on the same page. Please notify administrator.", "wp-file-upload"));
130
+ DEFINE("WFU_ERROR_CAPTCHA_MULTIPLE_NOTALLOWED_ADMIN", __("ERROR: Only one instance of RecaptchaV1 can exist on the same page. Please use RecaptchaV1 (no account).", "wp-file-upload"));
131
+ DEFINE("WFU_ERROR_CAPTCHA_NOSITEKEY", __("ERROR: No site key. Please contact administrator!", "wp-file-upload"));
132
+ DEFINE("WFU_ERROR_CAPTCHA_NOSITEKEY_ADMIN", __("ERROR: No site key defined! Please go to the plugin settings in Dashboard to define Google Recaptcha keys.", "wp-file-upload"));
133
+ DEFINE("WFU_ERROR_CAPTCHA_NOCHALLENGE", __("Bad captcha image!", "wp-file-upload"));
134
+ DEFINE("WFU_ERROR_CAPTCHA_NOINPUT", __("No input!", "wp-file-upload"));
135
+ DEFINE("WFU_ERROR_CAPTCHA_EMPTY", __("Captcha not completed!", "wp-file-upload"));
136
+ DEFINE("WFU_ERROR_CAPTCHA_WRONGCAPTCHA", __("Wrong captcha!", "wp-file-upload"));
137
+ DEFINE("WFU_ERROR_CAPTCHA_REFRESHING", __("Error refreshing captcha!", "wp-file-upload"));
138
+ DEFINE("WFU_ERROR_CAPTCHA_UNKNOWNERROR", __("Unknown captcha error!", "wp-file-upload"));
139
+ DEFINE("WFU_ERROR_CAPTCHA_NOTSUPPORTED", __("Captcha not supported by your browser!", "wp-file-upload"));
140
+ DEFINE("WFU_ERROR_CAPTCHA_MISSINGINPUTSECRET", __("the secret parameter is missing", "wp-file-upload"));
141
+ DEFINE("WFU_ERROR_CAPTCHA_INVALIDINPUTSECRET", __("the secret parameter is invalid or malformed", "wp-file-upload"));
142
+ DEFINE("WFU_ERROR_CAPTCHA_MISSINGINPUTRESPONSE", __("the response parameter is missing", "wp-file-upload"));
143
+ DEFINE("WFU_ERROR_CAPTCHA_INVALIDINPUTRESPONSE", __("the response parameter is invalid or malformed", "wp-file-upload"));
144
+ DEFINE("WFU_ERROR_REDIRECTION_NODRAGDROP", __("Please do not use drag drop due to an internal problem.", "wp-file-upload"));
145
+ DEFINE("WFU_ERROR_CHUNKEDUPLOAD_UNIQUEIDEMPTY", __("Error during chunked upload. Unique ID empty in chunk %d", "wp-file-upload"));
146
+ DEFINE("WFU_ERROR_CHUNKEDUPLOAD_NOTALLOWED", __("Chunked upload is not allowed!", "wp-file-upload"));
147
+ DEFINE("WFU_ERROR_CHUNKEDUPLOAD_ABORTED", __("Chunked upload aborted due to error in previous chunk!", "wp-file-upload"));
148
+ DEFINE("WFU_ERROR_CHUNKEDUPLOAD_CONCATFAILED", __("Chunked upload failed, final file could not be created!", "wp-file-upload"));
149
+ DEFINE("WFU_ERROR_ADMIN_CHUNKWRITEFAILED", __("Could not write file chuck to destination on chunk %d", "wp-file-upload"));
150
+ DEFINE("WFU_ERROR_ADMIN_CHUNKENLARGEFAILED", __("Could not enlarge destination file on chunk %d", "wp-file-upload"));
151
+ DEFINE("WFU_ERROR_ADMIN_CHUNKHANDLEFAILED", __("Could not open file handles on chunk %d", "wp-file-upload"));
152
+ DEFINE("WFU_BROWSER_DOWNLOADFILE_NOTALLOWED", __("You are not allowed to download this file!", "wp-file-upload"));
153
+ DEFINE("WFU_BROWSER_DOWNLOADFILE_NOTEXIST", __("File does not exist!", "wp-file-upload"));
154
+ DEFINE("WFU_BROWSER_DOWNLOADFILE_FAILED", __("Could not download file!", "wp-file-upload"));
155
+ DEFINE("WFU_BROWSER_DELETEFILE_NOTALLOWED", __("You are not allowed to delete this file!", "wp-file-upload"));
156
+ DEFINE("WFU_BROWSER_DELETEFILE_FAILED", __("File was not deleted!", "wp-file-upload"));
157
+ DEFINE("WFU_BROWSER_DELETEFILES_ALLFAILED", __("No file was deleted!", "wp-file-upload"));
158
+ DEFINE("WFU_BROWSER_DELETEFILES_SOMEFAILED", __("Some files were not deleted!", "wp-file-upload"));
159
+ //warning messages
160
+ DEFINE("WFU_WARNING_FILE_EXISTS", __("Upload skipped! File already exists.", "wp-file-upload"));
161
+ DEFINE("WFU_WARNING_FILE_SUSPICIOUS", __("The extension of the file does not match its contents.", "wp-file-upload"));
162
+ DEFINE("WFU_WARNING_ADMIN_FILE_SUSPICIOUS", __("Upload succeeded but the file is suspicious because its contents do not match its extension. Its proper filename is: ", "wp-file-upload"));
163
+ DEFINE("WFU_WARNING_NOFILES_SELECTED", __("No files have been selected!", "wp-file-upload"));
164
+ DEFINE("WFU_WARNING_CONSENT_NOTCOMPLETED", __("Please complete the consent question before continuing the upload!", "wp-file-upload"));
165
+ DEFINE("WFU_WARNING_WPFILEBASE_NOTUPDATED_NOFILES", __("WPFilebase Plugin not updated because there were no files uploaded.", "wp-file-upload"));
166
+ DEFINE("WFU_WARNING_NOTIFY_NOTSENT_NOFILES", __("Notification email was not sent because there were no files uploaded.", "wp-file-upload"));
167
+ DEFINE("WFU_WARNING_NOTIFY_NOTSENT_NORECIPIENTS", __("Notification email was not sent because no recipients were defined. Please check notifyrecipients attribute in the shortcode.", "wp-file-upload"));
168
+ DEFINE("WFU_WARNING_NOTIFY_NOTSENT_UNKNOWNERROR", __("Notification email was not sent due to an error. Please check notifyrecipients, notifysubject and notifymessage attributes for errors.", "wp-file-upload"));
169
+ DEFINE("WFU_WARNING_REDIRECT_NOTEXECUTED_EMPTY", __("Redirection not executed because redirection link is empty. Please check redirectlink attribute.", "wp-file-upload"));
170
+ DEFINE("WFU_WARNING_REDIRECT_NOTEXECUTED_FILESFAILED", __("Redirection not executed because not all files were successfully uploaded.", "wp-file-upload"));
171
+ DEFINE("WFU_WARNING_POTENTIAL_DOS_EMAIL_SUBJECT", __("Potential Denial-Of-Service Attack on {SITE}", "wp-file-upload"));
172
+ DEFINE("WFU_WARNING_POTENTIAL_DOS_EMAIL_MESSAGE", __("Hello admin\n\nThis is a message from Wordpress File Upload Plugin to notify you that a potential Denial-Of-Service attack has been detected on {SITE}.\n\nThe plugin detected more than {FILENUM} uploads within {INTERVAL} seconds.\n\nAll file uploads that exceed this limit are rejected to protect the website from overflowing.\n\nPlease check the upload history log in the plugin's area in Dashboard for any suspicious behaviour.\n\nA new message will follow if the situation remains.\n\nThanks", "wp-file-upload"));
173
+ DEFINE("WFU_WARNING_ALT_IPTANUS_SERVER_ACTIVATED", __("You have activated an alternative insecure Iptanus Services Server. For details please contact info@iptanus.com.", "wp-file-upload"));
174
+ DEFINE("WFU_WARNING_IPTANUS_SERVER_UNREACHABLE", __("Iptanus Services Server is unreachable. This may cause problems on some plugin functions. Please read this :article: for resolution.", "wp-file-upload"));
175
+ //admin area messages
176
+ DEFINE("WFU_DASHBOARD_ADD_SHORTCODE_REJECTED", __("Failed to add the shortcode to the page/post. Please try again. If the message persists, contact administrator.", "wp-file-upload"));
177
+ DEFINE("WFU_DASHBOARD_EDIT_SHORTCODE_REJECTED", __("Failed to edit the shortcode because the contents of the page changed. Try again to edit the shortcode.", "wp-file-upload"));
178
+ DEFINE("WFU_DASHBOARD_DELETE_SHORTCODE_REJECTED", __("Failed to delete the shortcode because the contents of the page changed. Try again to delete it.", "wp-file-upload"));
179
+ DEFINE("WFU_DASHBOARD_PAGE_OBSOLETE", __("The page containing the shortcode has been modified and it is no longer valid. Please go back to reload the shortcode.", "wp-file-upload"));
180
+ DEFINE("WFU_DASHBOARD_UPDATE_SHORTCODE_REJECTED", __("Failed to update the shortcode because the contents of the page changed. Go back to reload the shortcode.", "wp-file-upload"));
181
+ DEFINE("WFU_DASHBOARD_UPDATE_SHORTCODE_FAILED", __("Failed to update the shortcode. Please try again. If the problem persists, go back and reload the shortcode.", "wp-file-upload"));
182
+ //test messages
183
+ DEFINE("WFU_TESTMESSAGE_MESSAGE", __('This is a test message', 'wp-file-upload'));
184
+ DEFINE("WFU_TESTMESSAGE_ADMINMESSAGE", __('This is a test administrator message', 'wp-file-upload'));
185
+ DEFINE("WFU_TESTMESSAGE_FILE1_HEADER", __('File testfile 1 under test', 'wp-file-upload'));
186
+ DEFINE("WFU_TESTMESSAGE_FILE1_MESSAGE", __('File testfile 1 message', 'wp-file-upload'));
187
+ DEFINE("WFU_TESTMESSAGE_FILE1_ADMINMESSAGE", __('File testfile 1 administrator message', 'wp-file-upload'));
188
+ DEFINE("WFU_TESTMESSAGE_FILE2_HEADER", __('File testfile 2 under test', 'wp-file-upload'));
189
+ DEFINE("WFU_TESTMESSAGE_FILE2_MESSAGE", __('File testfile 2 message', 'wp-file-upload'));
190
+ DEFINE("WFU_TESTMESSAGE_FILE2_ADMINMESSAGE", __('File testfile 2 administrator message', 'wp-file-upload'));
191
+ //variables tool-tips
192
+ DEFINE("WFU_VARIABLE_TITLE_USERID", __("Insert variable %userid% inside text. It will be replaced by the id of the current user.", "wp-file-upload"));
193
+ DEFINE("WFU_VARIABLE_TITLE_USERNAME", __("Insert variable %username% inside text. It will be replaced by the username of the current user.", "wp-file-upload"));
194
+ DEFINE("WFU_VARIABLE_TITLE_USEREMAIL", __("Insert variable %useremail% inside text. It will be replaced by the email of the current user.", "wp-file-upload"));
195
+ DEFINE("WFU_VARIABLE_TITLE_FILENAME", __("Insert variable %filename% inside text. It will be replaced by the filename of the uploaded file.", "wp-file-upload"));
196
+ DEFINE("WFU_VARIABLE_TITLE_FILEPATH", __("Insert variable %filepath% inside text. It will be replaced by the full filepath of the uploaded file.", "wp-file-upload"));
197
+ DEFINE("WFU_VARIABLE_TITLE_BLOGID", __("Insert variable %blogid% inside text. It will be replaced by the blog id of the website.", "wp-file-upload"));
198
+ DEFINE("WFU_VARIABLE_TITLE_PAGEID", __("Insert variable %pageid% inside text. It will be replaced by the id of the current page.", "wp-file-upload"));
199
+ DEFINE("WFU_VARIABLE_TITLE_PAGETITLE", __("Insert variable %pagetitle% inside text. It will be replaced by the title of the current page.", "wp-file-upload"));
200
+ DEFINE("WFU_VARIABLE_TITLE_USERDATAXXX", __("Insert variable %userdataXXX% inside text. Select the user field from the drop-down list. It will be replaced by the value that the user entered in this field.", "wp-file-upload"));
201
+ DEFINE("WFU_VARIABLE_TITLE_N", __("Insert variable %n% inside text to denote a line change.", "wp-file-upload"));
202
+ //other plugin values
203
+ DEFINE("WFU_WARNINGMESSAGE_NOSAVE", __('File %filename% uploaded successfully but not saved', 'wp-file-upload'));
204
+ DEFINE("WFU_NOTIFY_TESTMODE", __("Test Mode", "wp-file-upload"));
205
+ DEFINE("WFU_SUBDIR_SELECTDIR", __("select dir...", "wp-file-upload"));
206
+ DEFINE("WFU_SUBDIR_TYPEDIR", __("type dir", "wp-file-upload"));
207
+ DEFINE("WFU_SUCCESSMESSAGE_DETAILS", __('Upload path: %filepath%', 'wp-file-upload'));
208
+ DEFINE("WFU_FAILMESSAGE_DETAILS", __('Failed upload path: %filepath%', 'wp-file-upload'));
209
+ DEFINE("WFU_USERDATA_REQUIREDLABEL", __(' (required)', 'wp-file-upload'));
210
+ DEFINE("WFU_PAGEEXIT_PROMPT", __('Files are being uploaded. Are you sure you want to exit the page?', 'wp-file-upload'));
211
+ DEFINE("WFU_MESSAGE_CAPTCHA_CHECKING", __("checking captcha...", "wp-file-upload"));
212
+ DEFINE("WFU_MESSAGE_CAPTCHA_REFRESHING", __("refreshing...", "wp-file-upload"));
213
+ DEFINE("WFU_MESSAGE_CAPTCHA_OK", __("correct captcha", "wp-file-upload"));
214
+ DEFINE("WFU_CONFIRMBOX_CAPTION", __("click to continue the upload", "wp-file-upload"));
215
+ DEFINE("WFU_BROWSER_DELETEFILE_PROMPT", __("Are you sure you want to delete this file?", "wp-file-upload"));
216
+ DEFINE("WFU_BROWSER_DELETEFILES_PROMPT", __("Are you sure you want to delete these files?", "wp-file-upload"));
217
+ DEFINE("WFU_BROWSER_BULKACTION_TITLE", __("Bulk Actions", "wp-file-upload"));
218
+ DEFINE("WFU_BROWSER_BULKACTION_LABEL", __("Apply", "wp-file-upload"));
219
+ DEFINE("WFU_PAGINATION_PAGE", __("Page", "wp-file-upload"));
220
+ DEFINE("WFU_PAGINATION_OF", __("of ", "wp-file-upload"));
221
+ DEFINE("WFU_CANCEL_UPLOAD_PROMPT", __("Are you sure that you want to cancel the upload?", "wp-file-upload"));
222
+ DEFINE("WFU_FILE_CANCEL_HINT", __("cancel upload of this file", "wp-file-upload"));
223
+ DEFINE("WFU_UPLOAD_STATE0", __("Upload in progress", "wp-file-upload"));
224
+ DEFINE("WFU_UPLOAD_STATE1", __("Upload in progress with warnings!", "wp-file-upload"));
225
+ DEFINE("WFU_UPLOAD_STATE2", __("Upload in progress but some files already failed!", "wp-file-upload"));
226
+ DEFINE("WFU_UPLOAD_STATE3", __("Upload in progress but no files uploaded so far!", "wp-file-upload"));
227
+ DEFINE("WFU_UPLOAD_STATE4", __("All files uploaded successfully", "wp-file-upload"));
228
+ DEFINE("WFU_UPLOAD_STATE5", __("All files uploaded successfully but there are warnings!", "wp-file-upload"));
229
+ DEFINE("WFU_UPLOAD_STATE5_SINGLEFILE", __("File uploaded successfully but there are warnings!", "wp-file-upload"));
230
+ DEFINE("WFU_UPLOAD_STATE6", __("Some files failed to upload!", "wp-file-upload"));
231
+ DEFINE("WFU_UPLOAD_STATE7", __("All files failed to upload", "wp-file-upload"));
232
+ DEFINE("WFU_UPLOAD_STATE7_SINGLEFILE", __("File failed to upload", "wp-file-upload"));
233
+ DEFINE("WFU_UPLOAD_STATE8", __("There are no files to upload!", "wp-file-upload"));
234
+ DEFINE("WFU_UPLOAD_STATE9", __("Test upload message", "wp-file-upload"));
235
+ DEFINE("WFU_UPLOAD_STATE10", __("JSON parse warning!", "wp-file-upload"));
236
+ DEFINE("WFU_UPLOAD_STATE11", __("please wait while redirecting...", "wp-file-upload"));
237
+ DEFINE("WFU_UPLOAD_STATE12", __("Upload failed!", "wp-file-upload"));
238
+ DEFINE("WFU_UPLOAD_STATE13", __("Submitting data", "wp-file-upload"));
239
+ DEFINE("WFU_UPLOAD_STATE14", __("Data submitted successfully!", "wp-file-upload"));
240
+ DEFINE("WFU_UPLOAD_STATE15", __("Data were not submitted!", "wp-file-upload"));
241
+ DEFINE("WFU_UPLOAD_STATE16", __("Cancelling upload", "wp-file-upload"));
242
+ DEFINE("WFU_UPLOAD_STATE17", __("Upload cancelled!", "wp-file-upload"));
243
+ DEFINE("WFU_UPLOAD_STATE18", __("Upload succeeded!", "wp-file-upload"));
244
+ DEFINE("WFU_UPLOAD_STATE19", __("Upload completed but no files were saved!", "wp-file-upload"));
245
+ DEFINE("WFU_UPLOAD_STATE19_SINGLEFILE", __("File was not saved due to personal data policy!", "wp-file-upload"));
246
+ DEFINE("WFU_PAGE_PLUGINEDITOR_BUTTONTITLE", __("Open visual shortcode editor in new window", "wp-file-upload"));
247
+ DEFINE("WFU_PAGE_PLUGINEDITOR_LOADING", __("loading visual editor", "wp-file-upload"));
248
+ DEFINE("WFU_CONFIRM_CLEARFILES", __("Clear file list?", "wp-file-upload"));
249
+ DEFINE("WFU_DROP_HERE_MESSAGE", __('DROP HERE', 'wp-file-upload'));
250
+ //webcam values
251
+ DEFINE("WFU_WEBCAM_RECVIDEO_BTN", __('record video', 'wp-file-upload'));
252
+ DEFINE("WFU_WEBCAM_TAKEPIC_BTN", __('take a picture', 'wp-file-upload'));
253
+ DEFINE("WFU_WEBCAM_TURNONOFF_BTN", __('turn webcam on/off', 'wp-file-upload'));
254
+ DEFINE("WFU_WEBCAM_GOLIVE_BTN", __('go live again', 'wp-file-upload'));
255
+ DEFINE("WFU_WEBCAM_STOPREC_BTN", __('end recording', 'wp-file-upload'));
256
+ DEFINE("WFU_WEBCAM_PLAY_BTN", __('play', 'wp-file-upload'));
257
+ DEFINE("WFU_WEBCAM_PAUSE_BTN", __('pause', 'wp-file-upload'));
258
+ DEFINE("WFU_WEBCAM_GOBACK_BTN", __('go to the beginning', 'wp-file-upload'));
259
+ DEFINE("WFU_WEBCAM_GOFWD_BTN", __('go to the end', 'wp-file-upload'));
260
+ //widget values
261
+ DEFINE("WFU_WIDGET_PLUGINFORM_TITLE", __('Wordpress File Upload Form', 'wp-file-upload'));
262
+ DEFINE("WFU_WIDGET_PLUGINFORM_DESCRIPTION", __('Wordpress File Upload plugin uploader for sidebars', 'wp-file-upload'));
263
+ DEFINE("WFU_WIDGET_SIDEBAR_DEFAULTTITLE", __('Upload Files', 'wp-file-upload'));
264
+ }
265
+
266
+ /*********** Environment Variables ************/
267
+ //plugin default values
268
+ $GLOBALS["WFU_GLOBALS"] = array(
269
+ "WFU_UPLOADID" => array( "Default Upload ID", "string", "1", "The default upload ID of the uploader shortcode. It can be any integer from 1 and above." ),
270
+ "WFU_SINGLEBUTTON" => array( "Default Single-Button Status", "string", "false", "The default single-button status of the uploader shortcode. It can be 'true' or 'false'." ),
271
+ "WFU_UPLOADROLE" => array( "Default Upload Role", "string", "all,guests", "The default upload role of the uploader shortcode. It can be a comma-separated list of role slugs, including keywords 'all' and 'guests'." ),
272
+ "WFU_UPLOADPATH" => array( "Default Upload Path", "string", "uploads", "The default upload path of the uploader shortcode. It must be a folder relative to wp-content dir." ),
273
+ "WFU_FITMODE" => array( "Default Fit Mode", "string", "fixed", "The default fit mode of the uploader shortcode. It can be 'fixed' or 'responsive'." ),
274
+ "WFU_ALLOWNOFILE" => array( "Default Allow No File Mode", "string", "false", "The default mode for allowing no file uploads. If it is set to 'true' then an upload form can be submitted even if a file has not been selected. It can be 'true' or 'false'." ),
275
+ "WFU_ALLOWNOFILE" => array( "Default Allow No File Mode", "string", "false", "The default mode for allowing no file uploads. If it is set to 'true' then an upload form can be submitted even if a file has not been selected. It can be 'true' or 'false'." ),
276
+ "WFU_RESETMODE" => array( "Default Reset Form Mode", "string", "always", "The default reset mode of the upload form. It can be 'always', 'onsuccess' or 'never'." ),
277
+ "WFU_FORCEFILENAME" => array( "Default Force Filename State", "string", "false", "The default force filename state (force plugin to leave filename unchanged) of the uploader shortcode. It can be 'true' or 'false'." ),
278
+ "WFU_UPLOADPATTERNS" => array( "Default Upload Extensions", "string", "*.*", "The default allowed file extensions of the uploader shortcode. It can be a comma-separated list of wildcard extensions." ),
279
+ "WFU_MAXSIZE" => array( "Default Maximum File Size", "string", "50", "The default maximum allowed file size of the uploader shortcode in Megabytes. It can be any positive number." ),
280
+ "WFU_ACCESSMETHOD" => array( "Default Access Method", "string", "normal", "The default access method (of the website filesystem) of the uploader shortcode. It can be 'normal' or 'ftp'." ),
281
+ "WFU_FTPINFO" => array( "Default FTP Access Information", "string", "", "The default FTP access parameters of the uploader shortcode. It's syntax is 'username:password@ftp_domain'." ),
282
+ "WFU_USEFTPDOMAIN" => array( "Default Use FTP Domain State", "string", "false", "The default use FTP domain state (use the FTP domain defined in ftpinfo to store the uploaded files) of the uploader shortcode. It can be 'true' or 'false'." ),
283
+ "WFU_FTPPASSIVEMODE" => array( "Default FTP Passive Mode State", "string", "false", "The default FTP passive mode (use passive mode or not for FTP access) of the uploader shortcode. It can be 'true' or 'false'." ),
284
+ "WFU_FTPFILEPERMISSIONS" => array( "Default FTP File Permissions", "string", "", "The default FTP passive mode (use passive mode or not for FTP access) of the uploader shortcode. It can be 'true' or 'false'." ),
285
+ "WFU_DUBLICATESPOLICY" => array( "Default Duplicate File Action", "string", "overwrite", "The default duplicate file action of the uploader shortcode. It can be 'overwrite', 'reject' or 'mantain both'." ),
286
+ "WFU_UNIQUEPATTERN" => array( "Default Duplicate File Pattern", "string", "index", "The default duplicate file pattern of the uploader shortcode. It can be 'index' or 'datetimestamp'." ),
287
+ "WFU_FILEBASELINK" => array( "Default WPFilebase Update State", "string", "false", "The default WPFilebase plugin update state of the uploader shortcode. It can be 'true' or 'false'." ),
288
+ "WFU_NOTIFY" => array( "Default Email Notification State", "string", "false", "The default email notification state of the uploader shortcode. It can be 'true' or 'false'." ),
289
+ "WFU_NOTIFYRECIPIENTS" => array( "Default Email Recipients", "string", "", "The default email recipients of the uploader shortcode. It can be a comma-separated list of email addresses." ),
290
+ "WFU_NOTIFYHEADERS" => array( "Default Email Headers", "string", "", "The default email headers of the uploader shortcode." ),
291
+ "WFU_ATTACHFILE" => array( "Default Attach File State", "string", "false", "The default attach file to email state of the uploader shortcode. It can be 'true' or 'false'." ),
292
+ "WFU_REDIRECT" => array( "Default Redirection State", "string", "false", "The default redirection state of the uploader shortcode. It can be 'true' or 'false'." ),
293
+ "WFU_REDIRECTLINK" => array( "Default Redirect URL", "string", "", "The default redirect URL of the uploader shortcode." ),
294
+ "WFU_ADMINMESSAGES" => array( "Default State for Admin Messages", "string", "false", "The default state of displaying or not admin messages of the uploader shortcode. It can be 'true' or 'false'." ),
295
+ "WFU_SUCCESSMESSAGECOLORS" => array( "Default Colors for Success Message", "string", "#006600,#EEFFEE,#006666", "The default color triplet (text, background and border colors) of success message of the uploader shortcode." ),
296
+ "WFU_WARNINGMESSAGECOLORS" => array( "Default Colors for Warning Message", "string", "#F88017,#FEF2E7,#633309", "The default color triplet (text, background and border colors) of warning message of the uploader shortcode." ),
297
+ "WFU_FAILMESSAGECOLORS" => array( "Default Colors for Fail Message", "string", "#660000,#FFEEEE,#666600", "The default color triplet (text, background and border colors) of fail message of the uploader shortcode." ),
298
+ "WFU_WAITMESSAGECOLORS" => array( "Default Colors for Wait Message", "string", "#666666,#EEEEEE,#333333", "The default color triplet (text, background and border colors) of wait message of the uploader shortcode." ),
299
+ "WFU_SHOWTARGETFOLDER" => array( "Default State for Target Folder", "string", "false", "The default state of displaying or not the target folder of the uploader shortcode. It can be 'true' or 'false'." ),
300
+ "WFU_TARGETFOLDERLABEL" => array( "Default Text for Target Folder Label", "string", "Upload Directory", "The default text of the target folder label of the uploader shortcode." ),
301
+ "WFU_ASKFORSUBFOLDERS" => array( "Default Subfolders State", "string", "false", "The default state of displaying or not a list of subfolders of the uploader shortcode. It can be 'true' or 'false'." ),
302
+ "WFU_SUBFOLDERLABEL" => array( "Default Text of Subfolders Label", "string", "Select Subfolder", "The default text of subfolders label of the uploader shortcode." ),
303
+ "WFU_SUBFOLDERTREE" => array( "Default Subfolders List", "string", "", "The default list of subfolders of the uploader shortcode. Check plugin's support page for syntax." ),
304
+ "WFU_FORCECLASSIC" => array( "Default Disable AJAX State", "string", "false", "The default state of disabling or not AJAX functionality of the uploader shortcode. It can be 'true' or 'false'." ),
305
+ "WFU_TESTMODE" => array( "Default Test Mode State", "string", "false", "The default state of test mode of the uploader shortcode. It can be 'true' or 'false'." ),
306
+ "WFU_DEBUGMODE" => array( "Default Debug Mode State", "string", "false", "The default state of debug mode of the uploader shortcode. It can be 'true' or 'false'." ),
307
+ "WFU_WIDTHS" => array( "Default Element Widths", "string", "", "The default widths of the elements of the uploader shortcode. It is a comma-separated list of element widths." ),
308
+ "WFU_HEIGHTS" => array( "Default Element Heights", "string", "", "The default heights of the elements of the uploader shortcode. It is a comma-separated list of element heights." ),
309
+ "WFU_PLACEMENTS" => array( "Default Element Placements", "string", "title/filename+selectbutton+uploadbutton/subfolders"."/userdata"."/message", "The default placements of the elements of the uploader shortcode. Check plugin's support page for syntax." ),
310
+ "WFU_USERDATA" => array( "Default User Fields State", "string", "false", "The default state of custom user fields of the uploader shortcode. It can be 'true' or 'false'." ),
311
+ "WFU_MEDIALINK" => array( "Default Add to Media State", "string", "false", "The default state for adding files to Media of the uploader shortcode. It can be 'true' or 'false'." ),
312
+ "WFU_POSTLINK" => array( "Default Attachment to Post State", "string", "false", "The default state for attaching files to current post of the uploader shortcode. It can be 'true' or 'false'." ),
313
+ "WFU_WEBCAM" => array( "Default Webcam State", "string", "false", "The default state for webcam capture. It can be 'true' or 'false'." ),
314
+ "WFU_AUDIOCAPTURE" => array( "Default Capture Audio State", "string", "false", "The default state of audio capture. If it is set to 'true' then audio will be captured, together with video from the webcam. It can be 'true' or 'false'." ),
315
+ "WFU_WEBCAMMODE" => array( "Default Webcam Mode", "string", "capture video", "The default webcam capture mode. It can be 'capture video', 'take photos' or 'both'." ),
316
+ "WFU_VIDEOWIDTH" => array( "Default Video Width", "string", "", "The default preferable video width for webcam capture. It can be any positive integer in pixels." ),
317
+ "WFU_VIDEOHEIGHT" => array( "Default Video Height", "string", "", "The default preferable video height for webcam capture. It can be any positive integer in pixels." ),
318
+ "WFU_VIDEOASPECTRATIO" => array( "Default Video Aspect Ratio", "string", "", "The default preferable video aspect ratio for webcam video capture. It can be any positive value." ),
319
+ "WFU_VIDEOFRAMERATE" => array( "Default Video Frame Rate", "string", "", "The default preferable video frame rate for webcam video capture. It can be any positive value in frames/sec." ),
320
+ "WFU_CAMERAFACING" => array( "Default Camera Facing Mode", "string", "any", "The default preferable camera to be used for video/screenshot capture. It can be 'any', 'front' or 'back'." ),
321
+ "WFU_MAXRECORDTIME" => array( "Default Maximum Record Time", "string", "10", "The default maximum video recording time in seconds. The default value is 10 seconds." ),
322
+ "WFU_ASKCONSENT" => array( "Default Ask Consent State", "string", "false", "The default state of personal data consent request. The default value is false." ),
323
+ "WFU_PERSONALDATATYPES" => array( "Default Personal Data Types", "string", "userdata", "The default personal data types. The default value is 'userdata'." ),
324
+ "WFU_NOTREMEMBERCONSENT" => array( "Default Do Not Remember Consent Answer State", "string", "false", "The default state about remembering or not user's answer on consent question. The default value is true." ),
325
+ "WFU_CONSENTREJECTUPLOAD" => array( "Default Reject Upload on Consent Denial State", "string", "false", "The default state of continuing or rejecting the upload depending on consent answer. The default value is true." ),
326
+ "WFU_CONSENTFORMAT" => array( "Default Consent Format", "string", "radio", "The default format of consent question. The default value is 'checkbox'." ),
327
+ "WFU_CONSENTPRESELECT" => array( "Default Consent Preselect State", "string", "none", "The default preselect state of consent question when checkbox format is active. The default value is false." )
328
+ );
329
+ //other plugin values
330
+ $GLOBALS["WFU_GLOBALS"] += array(
331
+ "WFU_DEBUG" => array( "Plugin Debug Mode", "string", "OFF", "If DEBUG mode is activated then advanced hook of plugin's function can be performed. This option may make the plugin slower, so use it very carefully. It can be 'OFF' or 'ON'." ),
332
+ "WFU_RESTRICT_FRONTEND_LOADING" => array( "Restrict Front-End Loading", "string", "false", "It defines whether the plugin will load on all pages or specific ones. If it is 'false' then it will load on all pages. To restrict loading only on specific pages set a comma-separated list of page or post IDs." ),
333
+ "WFU_UPLOADPROGRESS_MODE" => array( "Upload Progress Mode", "string", "incremental", "Defines how the upload progress is calculated. It can be 'incremental' or 'absolute'. Default value is 'incremental'." ),
334
+ "WFU_DOS_ATTACKS_CHECK" => array( "Check for Denial-Of-Service Attacks", "string", "true", "If it is true then then plugin will check if the number of files uploaded within a specific amount of time exceeds the limit, thus protecting from DOS attacks. It can be 'true' or 'false'." ),
335
+ "WFU_DOS_ATTACKS_FILE_LIMIT" => array( "Denial-Of-Service File Limit", "integer", 10000, "Defines the maximum number of files that are allowed to be uploaded within a specific amount of time. It can be any positive integer." ),
336
+ "WFU_DOS_ATTACKS_TIME_INTERVAL" => array( "Denial-Of-Service Time Interval", "integer", 3600, "Defines the time interval for DOS attacks check. The time interval is given in seconds." ),
337
+ "WFU_DOS_ATTACKS_ADMIN_EMAIL_FREQUENCY" => array( "Denial-Of-Service Admin Email Frequency", "integer", 3600, "Defines how frequently an email will be sent to administrator notifying for Denial-Of-Service attacks. The time interval is given in seconds." ),
338
+ "WFU_SANITIZE_FILENAME_MODE" => array( "Filename Sanitization Mode", "string", "strict", "The sanitization mode for filenames. It can be 'strict' or 'loose'." ),
339
+ "WFU_SANITIZE_FILENAME_DOTS" => array( "Sanitize Filename Dots", "string", "true", "Convert dot symbols (.) in filename into dashes, in order to avoid double extensions. It can be 'true' or 'false'." ),
340
+ "WFU_WILDCARD_ASTERISK_MODE" => array( "Wildcard Asterisk Mode", "string", "strict", "The mode of wildcard pattern asterisk symbol. If it is strict, then the asterisk will not match dot (.) characters. It can be 'strict' or 'loose'." ),
341
+ "WFU_CHECKPHPTAGS_FILETYPES" => array( "PHP Tag Checking File Types", "string", "commonimages", "The file types for which the plugin will check their contents for PHP tags. It can be 'all', 'commonimages' or 'none'." ),
342
+ "WFU_PHP_ARRAY_MAXLEN" => array( "Max PHP Array Length", "string", "10000", "The maximum allowable number of items of a PHP array." ),
343
+ "WFU_ADMINBROWSER_TABLE_MAXROWS" => array( "Admin Browser Rows Per Page", "integer", 25, "The number of rows per page of the admin browser. A value equal to zero or less denotes no pagination." ),
344
+ "WFU_HISTORYLOG_TABLE_MAXROWS" => array( "History Log Table Rows Per Page", "integer", 25, "The number of rows per page of the History Log table." ),
345
+ "WFU_UPLOADEDFILES_TABLE_MAXROWS" => array( "Uploaded Files Table Rows Per Page", "integer", 25, "The number of rows per page of the Uploaded Files table." ),
346
+ "WFU_ALTERNATIVE_RANDOMIZER" => array( "Use Alternative Randomizer", "string", "false", "On fast web servers the plugin's generator of random strings may not work properly causing various problems. If it is set to true, an alternative randomizer method is employed that works for fast web servers. It can be 'true' or 'false'." ),
347
+ "WFU_FORCE_NOTIFICATIONS" => array( "Force Email Notifications", "string", "false", "Send email notifications (if they are activated) even if no file has been uploaded. It can be 'true' or 'false'." ),
348
+ "WFU_UPDATE_MEDIA_ON_DELETE" => array( "Update Media on Delete", "string", "true", "When an uploaded file is deleted then delete also the corresponding Media Library item if exists. It can be 'true' or 'false'." ),
349
+ "WFU_DASHBOARD_PROTECTED" => array( "Dashboard Is Protected", "string", "false", "If /wp-admin folder is password protected then this variable should be set to 'true' so that internal operations of the plugin can work. The username and password should also be set." ),
350
+ "WFU_DASHBOARD_USERNAME" => array( "Protected Dashboard Username", "string", "", "Username entry for accessing protected /wp-admin folder." ),
351
+ "WFU_DASHBOARD_PASSWORD" => array( "Protected Dashboard Password", "string", "", "Password entry for accessing protected /wp-admin folder." ),
352
+ "WFU_EXPORT_DATA_SEPARATOR" => array( "Export Data Separator", "string", ",", "This is the delimiter of the exported file data columns. It can be any symbol. Default value is comma (,)." ),
353
+ "WFU_EXPORT_USERDATA_SEPARATOR" => array( "Export User Data Separator", "string", ";", "This is the delimiter of the exported user data of each file. It can be any symbol. Default value is semicolon (;)." ),
354
+ "WFU_DISABLE_VERSION_CHECK" => array( "Disable Version Check", "string", "false", "If it is set to 'true' then the plugin will not check if there are any new versions available. This is a temporary solution to problems having some users accessing Iptanus Services server causing the plugin to stall. It can be 'true' or 'false'." ),
355
+ "WFU_RELAX_CURL_VERIFY_HOST" => array( "Relax cURL Host Verification", "string", "false", "If it is set to 'true' then CURLOPT_SSL_VERIFYHOST will be disabled when executing a cURL POST request. This is required in some cases so that the plugin can reach https://services2.iptanus.com, because on some servers it fails with a file_get_contents warning. It can be 'true' or 'false'." ),
356
+ "WFU_USE_ALT_IPTANUS_SERVER" => array( "Use Alternative Iptanus Server", "string", "false", "If it is set to 'true' then the alternative Iptanus server will be used. This is a work-around in some cases where the website cannot reach https://services2.iptanus.com. It can be 'true' or 'false'." ),
357
+ "WFU_ALT_IPTANUS_SERVER" => array( "Alternative Iptanus Server", "string", "https://iptanusservices.appspot.com", "If it is set then this is the URL of the alternative Iptanus server." ),
358
+ "WFU_ALT_VERSION_SERVER" => array( "Alternative Version Server", "string", "https://iptanusservices.appspot.com/g79xo30q8s", "If the alternative Iptanus server is used and this variable is not empty, then it will be used as the alternative Version Server URL." ),
359
+ "WFU_MINIFY_INLINE_CSS" => array( "Minify Inline CSS Code", "string", "true", "Defines whether the inline CSS code will be minified. It can be 'true' or 'false'." ),
360
+ "WFU_MINIFY_INLINE_JS" => array( "Minify Inline JS Code", "string", "true", "Defines whether the inline Javascript code will be minified. It can be 'true' or 'false'." ),
361
+ "WFU_US_SESSION_LEGACY" => array( "Session Legacy Option", "string", "true", "Defines whether the old (legacy) operation of reading and storing session data (using session_start in header) will be used. By default it is set to 'true' to maintain backward compatibility." ),
362
+ "WFU_US_COOKIE_LIFE" => array( "Session Cookie Life", "integer", 48, "Defines the life of session cookie, in hours." ),
363
+ "WFU_US_DBOPTION_BASE" => array( "DB Option User State Base", "string", "cookies", "Defines how DB option defines the unique user state key. It can take the values 'session' or 'cookies'." ),
364
+ "WFU_US_DBOPTION_CHECK" => array( "DB Option User State Check Interval", "integer", 7200, "Defines how often (in seconds) the plugin will update user state list, when user state is saved in DB option table." ),
365
+ "WFU_US_DBOPTION_LIFE" => array( "DB Option User State Life", "integer", 1800, "Defines the maximum time of inactivity of a user state, when user state is saved in DB option table." ),
366
+ "WFU_US_HANDLER_CHANGED" => array( "User State Handler Changed", "string", "false", "Defines whether the plugin changed automatically the user state handler during installation." ),
367
+ "WFU_US_DBOPTION_USEOLD" => array( "Use Old DB Option Handler", "string", "false", "Defines whether the old DBOption user state handlers will be used." ),
368
+ "WFU_US_DEADLOCK_TIMEOUT" => array( "Database Deadlock Timeout", "integer", 10, "Defines for how long a deadlocked database transaction will be repeated." ),
369
+ "WFU_US_LOG_DBERRORS" => array( "Log Database Errors", "string", "false", "Defines whether database errors will be logged." ),
370
+ "WFU_QUEUE_ACTIVE" => array( "Enable Queue Functionality", "string", "true", "Defines whether queue operation is active." ),
371
+ "WFU_QUEUE_THREAD_TIMEOUT" => array( "Queue Thread Timeout", "integer", 5, "Defines for how long, in seconds, a queue will wait for a thread to finish before aborting the operation." ),
372
+ "WFU_QUEUE_LOOP_DELAY" => array( "Queue Loop Delay", "integer", 100, "Defines the time, in milliseconds, a wait loop will sleep before continuing." ),
373
+ "WFU_PD_VISIBLE_OPLEVELS" => array( "Personal Data Visible Operation Levels", "integer", 3, "Defines how deep administrators can go into personal data operation details. A value of -1 denotes that there is no limit." ),
374
+ "WFU_PD_VISIBLE_PERLEVELS" => array( "Personal Data Visible Permission Levels", "integer", 2, "Defines how deep administrators can go into personal data permission details. A value of -1 denotes that there is no limit." ),
375
+ "WFU_PD_VISIBLE_LOGLEVELS" => array( "Personal Data Visible Log Action Levels", "integer", 2, "Defines how deep administrators can go into personal data log action details. A value of -1 denotes that there is no limit." ),
376
+ "WFU_UPLOADEDFILES_MENU" => array( "Uploaded Files Menu State", "string", "true", "Defines whether the Uploaded Files Dashboard menu item will be shown or not. It can be 'true' or 'false'." ),
377
+ "WFU_UPLOADEDFILES_DEFACTION" => array( "Uploaded Files Default Action", "string", "adminbrowser", "Defines the default action that will be executed when a file link is pressed in Uploaded Files page. It can be 'details', 'adminbrowser', 'historylog', 'link', 'download' and 'none'." ),
378
+ "WFU_UPLOADEDFILES_COLUMNS" => array( "Uploaded Files Columns", "string", "#, file, upload_date, user, properties, remarks, actions", "Defines the visible columns of the Uploaded Files list as well as their order. It is noted that 'File' column is always visible and it is the second column if '#' column is visible, or the first one if '#' column is hidden." ),
379
+ "WFU_UPLOADEDFILES_ACTIONS" => array( "Uploaded Files Actions", "string", "details, media, adminbrowser, historylog, link, download, remotelinks", "Defines the allowable actions and their order for each file in Uploaded Files list. It is noted that the actions shown for each file depend on its properties." ),
380
+ "WFU_UPLOADEDFILES_HIDEINVALID" => array( "Hide Invalid Uploaded Files", "string", "false", "Defines whether all uploaded file records will be shown in Uploaded File menu or only the valid ones. Invalid are the records who are obsolete or their files do not exist anymore." ),
381
+ "WFU_UPLOADEDFILES_RESET_TIME" => array( "Uploaded Files Reset Time", "integer", 5, "Defines the interval in seconds before the unread uploaded files can be marked as read. A value of -1 denotes that there is no interval." ),
382
+ "WFU_UPLOADEDFILES_BARMENU" => array( "Uploaded Files Toolbar Menu State", "string", "true", "Defines whether the Uploaded Files Toolbar (Admin Bar) menu item will be shown or not. It can be 'true' or 'false'." ),
383
+ "WFU_UPLOADEDFILES_BARAUTOHIDE" => array( "Uploaded Files Auto-Hide on Toolbar", "string", "false", "Defines whether the Uploaded Files Toolbar (Admin Bar) menu item will be hidden when there are no new uploads. It can be 'true' or 'false'." ),
384
+ "WFU_SHORTCODECOMPOSER_NOADMIN" => array( "Show Shortcode Composer to Non-Admins", "string", "true", "Defines whether the shortcode composer will be visible to non-admin users who can edit posts or pages. It can be 'true' or 'false'." ),
385
+ "WFU_FILEOPERATION_IGNOREFTP" => array( "Ignore FTP Path in File Operations", "string", "false", "Defines whether file functions, such as file_exists(), stat() etc. will be ignored for FTP paths. It can be 'true' or 'false'." ),
386
+ "WFU_FTPFILEEXISTS_DEFVALUE" => array( "Default Value of File Exists for FTP Paths", "string", "true", "Defines the default value that will be returned when file_exists() function is executed on an FTP path. It can be '*true', '*false', '*calc', 'true' or 'false'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
387
+ "WFU_FTPSTAT_DEFVALUE" => array( "Default Value of Stat for FTP Paths", "string", "empty", "Defines the default value that will be returned when stat() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
388
+ "WFU_FTPFILESIZE_DEFVALUE" => array( "Default Value of Filesize for FTP Paths", "string", "empty", "Defines the default value that will be returned when filesize() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
389
+ "WFU_FTPFOPEN_DEFVALUE" => array( "Default Value of Fopen for FTP Paths", "string", "empty", "Defines the default value that will be returned when fopen() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
390
+ "WFU_FTPFILEGETCONTENTS_DEFVALUE" => array( "Default Value of File Get Contents for FTP Paths", "string", "empty", "Defines the default value that will be returned when file_get_contents() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
391
+ "WFU_FTPMD5FILE_DEFVALUE" => array( "Default Value of MD5 File for FTP Paths", "string", "empty", "Defines the default value that will be returned when md5_file() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
392
+ "WFU_FTPUNLINK_DEFVALUE" => array( "Default Value of Unlink for FTP Paths", "string", "empty", "Defines the default value that will be returned when unlink() function is executed on an FTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREFTP." ),
393
+ "WFU_FILEOPERATION_IGNORESFTP" => array( "Ignore SFTP Path in File Operations", "string", "false", "Defines whether file functions, such as file_exists(), stat() etc. will be ignored for SFTP paths. It can be 'true' or 'false'." ),
394
+ "WFU_SFTPFILEEXISTS_DEFVALUE" => array( "Default Value of File Exists for SFTP Paths", "string", "true", "Defines the default value that will be returned when file_exists() function is executed on an SFTP path. It can be '*true', '*false', '*calc', 'true' or 'false'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
395
+ "WFU_SFTPSTAT_DEFVALUE" => array( "Default Value of Stat for SFTP Paths", "string", "empty", "Defines the default value that will be returned when stat() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
396
+ "WFU_SFTPFILESIZE_DEFVALUE" => array( "Default Value of Filesize for SFTP Paths", "string", "empty", "Defines the default value that will be returned when filesize() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
397
+ "WFU_SFTPFOPEN_DEFVALUE" => array( "Default Value of Fopen for SFTP Paths", "string", "empty", "Defines the default value that will be returned when fopen() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
398
+ "WFU_SFTPFILEGETCONTENTS_DEFVALUE" => array( "Default Value of File Get Contents for SFTP Paths", "string", "empty", "Defines the default value that will be returned when file_get_contents() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
399
+ "WFU_SFTPMD5FILE_DEFVALUE" => array( "Default Value of MD5 File for SFTP Paths", "string", "empty", "Defines the default value that will be returned when md5_file() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
400
+ "WFU_SFTPUNLINK_DEFVALUE" => array( "Default Value of Unlink for SFTP Paths", "string", "empty", "Defines the default value that will be returned when unlink() function is executed on an SFTP path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNORESFTP." ),
401
+ "WFU_FILEOPERATION_IGNOREREMOTE" => array( "Ignore Remote Path in File Operations", "string", "true", "Defines whether file functions, such as file_exists(), stat() etc. will be ignored for remote (cloud) paths. It can be 'true' or 'false'." ),
402
+ "WFU_REMOTEFILEEXISTS_DEFVALUE" => array( "Default Value of File Exists for Remote Paths", "string", "true", "Defines the default value that will be returned when file_exists() function is executed on a remote (cloud) path. It can be '*true', '*false', '*calc', 'true' or 'false'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREREMOTE." ),
403
+ "WFU_REMOTESTAT_DEFVALUE" => array( "Default Value of Stat for Remote Paths", "string", "empty", "Defines the default value that will be returned when stat() function is executed on a remote (cloud) path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREREMOTE." ),
404
+ "WFU_REMOTEFILESIZE_DEFVALUE" => array( "Default Value of Filesize for Remote Paths", "string", "empty", "Defines the default value that will be returned when filesize() function is executed on a remote (cloud) path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREREMOTE." ),
405
+ "WFU_REMOTEFOPEN_DEFVALUE" => array( "Default Value of Fopen for Remote Paths", "string", "empty", "Defines the default value that will be returned when fopen() function is executed on a remote (cloud) path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREREMOTE." ),
406
+ "WFU_REMOTEFILEGETCONTENTS_DEFVALUE" => array( "Default Value of File Get Contents for Remote Paths", "string", "empty", "Defines the default value that will be returned when file_get_contents() function is executed on a remote path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREREMOTE." ),
407
+ "WFU_REMOTEMD5FILE_DEFVALUE" => array( "Default Value of MD5 File for Remote Paths", "string", "empty", "Defines the default value that will be returned when md5_file() function is executed on a remote (cloud) path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREREMOTE." ),
408
+ "WFU_REMOTEUNLINK_DEFVALUE" => array( "Default Value of Unlink for Remote Paths", "string", "empty", "Defines the default value that will be returned when unlink() function is executed on a remote (cloud) path. It can be '*empty', '*calc' or 'empty'. If it starts with asterisk (*) then this variable takes precedence over the more general WFU_FILEOPERATION_IGNOREREMOTE." ),
409
+ );
410
+ //color definitions
411
+ $GLOBALS["WFU_GLOBALS"] += array(
412
+ "WFU_TESTMESSAGECOLORS" => array( "Colors for Message in Test Mode", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message in Test mode of the uploader shortcode." ),
413
+ "WFU_DEFAULTMESSAGECOLORS" => array( "Defaults Message Colors", "string", "#666666,#EEEEEE,#333333", "The default color triplet (text, background and border colors) of message of the uploader shortcode." ),
414
+ "WFU_HEADERMESSAGECOLORS_STATE0" => array( "State 0 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 0 (upload in progress with no messages) of the uploader shortcode." ),
415
+ "WFU_HEADERMESSAGECOLORS_STATE1" => array( "State 1 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 1 (upload in progress with messages) of the uploader shortcode." ),
416
+ "WFU_HEADERMESSAGECOLORS_STATE2" => array( "State 2 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 2 (upload in progress with some files not uploaded) of the uploader shortcode." ),
417
+ "WFU_HEADERMESSAGECOLORS_STATE3" => array( "State 3 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 3 (upload in progress with no files uploaded so far) of the uploader shortcode." ),
418
+ "WFU_HEADERMESSAGECOLORS_STATE4" => array( "State 4 Message Colors", "string", "#006600,#EEFFEE,#006666", "The color triplet (text, background and border colors) of message of upload state 4 (all files uploaded) of the uploader shortcode." ),
419
+ "WFU_HEADERMESSAGECOLORS_STATE5" => array( "State 5 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 5 (all files uploaded with messages) of the uploader shortcode." ),
420
+ "WFU_HEADERMESSAGECOLORS_STATE6" => array( "State 6 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 6 (some files not uploaded) of the uploader shortcode." ),
421
+ "WFU_HEADERMESSAGECOLORS_STATE7" => array( "State 7 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 7 (no files uploaded) of the uploader shortcode." ),
422
+ "WFU_HEADERMESSAGECOLORS_STATE8" => array( "State 8 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 8 (there are no files to upload) of the uploader shortcode." ),
423
+ "WFU_HEADERMESSAGECOLORS_STATE9" => array( "State 9 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 9 (test state) of the uploader shortcode." ),
424
+ "WFU_HEADERMESSAGECOLORS_STATE10" => array( "State 10 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 10 (JSON parse error) of the uploader shortcode." ),
425
+ "WFU_HEADERMESSAGECOLORS_STATE11" => array( "State 11 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 11 (redirecting) of the uploader shortcode." ),
426
+ "WFU_HEADERMESSAGECOLORS_STATE12" => array( "State 12 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 12 (upload failed) of the uploader shortcode." ),
427
+ "WFU_HEADERMESSAGECOLORS_STATE13" => array( "State 13 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 13 (sending data) of the uploader shortcode." ),
428
+ "WFU_HEADERMESSAGECOLORS_STATE14" => array( "State 14 Message Colors", "string", "#006600,#EEFFEE,#006666", "The color triplet (text, background and border colors) of message of upload state 14 (data submit succeeded) of the uploader shortcode." ),
429
+ "WFU_HEADERMESSAGECOLORS_STATE15" => array( "State 15 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 15 (data submit failed) of the uploader shortcode." ),
430
+ "WFU_HEADERMESSAGECOLORS_STATE16" => array( "State 16 Message Colors", "string", "#666666,#EEEEEE,#333333", "The color triplet (text, background and border colors) of message of upload state 16 (cancelling upload) of the uploader shortcode." ),
431
+ "WFU_HEADERMESSAGECOLORS_STATE17" => array( "State 17 Message Colors", "string", "#660000,#FFEEEE,#666600", "The color triplet (text, background and border colors) of message of upload state 17 (upload cancelled) of the uploader shortcode." ),
432
+ "WFU_HEADERMESSAGECOLORS_STATE18" => array( "State 18 Message Colors", "string", "#006600,#EEFFEE,#006666", "The color triplet (text, background and border colors) of message of upload state 18 (upload succeeded) of the uploader shortcode." ),
433
+ "WFU_HEADERMESSAGECOLORS_STATE19" => array( "State 19 Message Colors", "string", "#F88017,#FEF2E7,#633309", "The color triplet (text, background and border colors) of message of upload state 19 (upload completed but no files were saved due to personal data policy) of the uploader shortcode." )
434
+ );
435
+ //insert saved values to array
436
+ $envars = get_option("wfu_environment_variables", array());
437
+ foreach ( $GLOBALS["WFU_GLOBALS"] as $ind => $envar ) {
438
+ if ( isset($envars[$ind]) ) {
439
+ if ( $envar[1] == "integer" ) $saved = (int)$envars[$ind];
440
+ else $saved = (string)$envars[$ind];
441
+ }
442
+ else $saved = $envar[2];
443
+ array_splice($GLOBALS["WFU_GLOBALS"][$ind], 3, 0, array( $saved ));
444
+ //add visibility
445
+ $GLOBALS["WFU_GLOBALS"][$ind][5] = true;
446
+ }
447
+
448
+ //hide unwanted environment variables
449
+ $GLOBALS["WFU_GLOBALS"]["WFU_RELAX_CURL_VERIFY_HOST"][5] = false;
450
+ $GLOBALS["WFU_GLOBALS"]["WFU_USE_ALT_IPTANUS_SERVER"][5] = false;
451
+
452
+ /************** Constant Values ***************/
453
+ //other plugin values
454
+ DEFINE("WFU_SUCCESSMESSAGECOLOR", "green");
455
+ DEFINE("WFU_MAX_TIME_LIMIT", ini_get("max_input_time"));
456
+ DEFINE("WFU_RESPONSE_URL", WPFILEUPLOAD_DIR."wfu_response.php");
457
+ DEFINE("WFU_SERVICES_SERVER_URL", 'https://services2.iptanus.com');
458
+ DEFINE("WFU_VERSION_SERVER_URL", WFU_SERVICES_SERVER_URL.'/wp-admin/admin-ajax.php');
459
+ DEFINE("WFU_VERSION_HASH", '9npWpXMhAQ5e6AGJ5zqbaPxLk9ePD3eSu3WKeN9p89E9wmgL2PHtrqXPzBVpStzh');
460
+ DEFINE("WFU_DOWNLOADER_URL", WPFILEUPLOAD_DIR."wfu_file_downloader.php");
461
+ DEFINE("WFU_IPTANUS_SERVER_UNREACHABLE_ARTICLE", 'https://www.iptanus.com/iptanus-services-server-unreachable-error-wfu-plugin/');
462
+ //alternative insecure server
463
+ DEFINE("WFU_SERVICES_SERVER_ALT_URL", 'http://services.iptanus.com');
464
+ DEFINE("WFU_VERSION_SERVER_ALT_URL", WFU_SERVICES_SERVER_ALT_URL.'/wp-admin/admin-ajax.php');
465
+ DEFINE("WFU_PRO_VERSION_URL", 'https://www.iptanus.com/product/wordpress-file-upload-pro/');
466
+ //define images
467
+ DEFINE("WFU_IMAGE_ADMIN_HELP", WPFILEUPLOAD_DIR.'images/help_16.png');
468
+ DEFINE("WFU_IMAGE_ADMIN_RESTOREDEFAULT", WPFILEUPLOAD_DIR.'images/restore_16.png');
469
+ DEFINE("WFU_IMAGE_ADMIN_USERDATA_ADD", WPFILEUPLOAD_DIR.'images/add_12.png');
470
+ DEFINE("WFU_IMAGE_ADMIN_USERDATA_REMOVE", WPFILEUPLOAD_DIR.'images/remove_12.png');
471
+ DEFINE("WFU_IMAGE_ADMIN_USERDATA_UP", WPFILEUPLOAD_DIR.'images/up_12.png');
472
+ DEFINE("WFU_IMAGE_ADMIN_USERDATA_DOWN", WPFILEUPLOAD_DIR.'images/down_12.png');
473
+ DEFINE("WFU_IMAGE_ADMIN_SUBFOLDER_BROWSE", WPFILEUPLOAD_DIR.'images/tree_16.gif');
474
+ DEFINE("WFU_IMAGE_ADMIN_SUBFOLDER_OK", WPFILEUPLOAD_DIR.'images/ok_12.gif');
475
+ DEFINE("WFU_IMAGE_ADMIN_SUBFOLDER_CANCEL", WPFILEUPLOAD_DIR.'images/cancel_12.gif');
476
+ DEFINE("WFU_IMAGE_ADMIN_SUBFOLDER_LOADING", WPFILEUPLOAD_DIR.'images/refresh_16.gif');
477
+ DEFINE("WFU_IMAGE_SIMPLE_PROGBAR", WPFILEUPLOAD_DIR.'images/progbar.gif');
478
+ DEFINE("WFU_IMAGE_OVERLAY_EDITOR", WPFILEUPLOAD_DIR.'images/pencil.svg');
479
+ DEFINE("WFU_IMAGE_OVERLAY_LOADING", WPFILEUPLOAD_DIR.'images/loading_icon.gif');
480
+ DEFINE("WFU_IMAGE_FILE_CANCEL", WPFILEUPLOAD_DIR.'images/cancel_16.png');
481
+ DEFINE("WFU_IMAGE_MEDIA_BUTTONS", WPFILEUPLOAD_DIR.'images/open-iconic.svg');
482
+ DEFINE("WFU_IMAGE_VERSION_COMPARISON", WPFILEUPLOAD_DIR.'images/Version Comparison.png');
483
+
484
+ /**
485
+ * Front-End Constants Initialization
486
+ *
487
+ * This function initializes all constants that need to be passed to the front-
488
+ * end scripts of the upload form.
489
+ *
490
+ * @since 2.1.2
491
+ */
492
+ function wfu_set_javascript_constants() {
493
+ $consts = array(
494
+ "notify_testmode" => WFU_NOTIFY_TESTMODE,
495
+ "nofilemessage" => WFU_ERROR_UPLOAD_NOFILESELECTED,
496
+ "enable_popups" => WFU_ERROR_ENABLE_POPUPS,
497
+ "remoteserver_noresult" => WFU_ERROR_REMOTESERVER_NORESULT,
498
+ "message_header" => WFU_ERRORMESSAGE,
499
+ "message_failed" => WFU_ERROR_UPLOAD_FAILED_WHILE,
500
+ "message_cancelled" => WFU_ERROR_UPLOAD_CANCELLED,
501
+ "message_unknown" => WFU_ERROR_UNKNOWN,
502
+ "adminmessage_unknown" => WFU_FAILMESSAGE_DETAILS,
503
+ "message_timelimit" => WFU_ERROR_FILE_PHP_TIME,
504
+ "message_admin_timelimit" => WFU_ERROR_ADMIN_FILE_PHP_TIME,
505
+ "cancel_upload_prompt" => WFU_CANCEL_UPLOAD_PROMPT,
506
+ "file_cancelled" => WFU_ERROR_FILE_CANCELLED,
507
+ "jsonparse_filemessage" => WFU_ERROR_JSONPARSE_FILEMESSAGE,
508
+ "jsonparse_message" => WFU_ERROR_JSONPARSE_MESSAGE,
509
+ "jsonparse_adminmessage" => WFU_ERROR_JSONPARSE_ADMINMESSAGE,
510
+ "jsonparse_headermessage" => WFU_ERROR_JSONPARSE_HEADERMESSAGE,
511
+ "jsonparse_headeradminmessage" => WFU_ERROR_JSONPARSE_HEADERADMINMESSAGE,
512
+ "same_pluginid" => WFU_ERROR_SAME_PLUGINID,
513
+ "webcam_video_notsupported" => WFU_ERROR_WEBCAM_VIDEO_NOTSUPPORTED,
514
+ "webcam_video_nothingrecorded" => WFU_ERROR_WEBCAM_VIDEO_NOTHINGRECORDED,
515
+ "default_colors" => WFU_VAR("WFU_DEFAULTMESSAGECOLORS"),
516
+ "fail_colors" => WFU_VAR("WFU_FAILMESSAGECOLORS"),
517
+ "max_time_limit" => WFU_MAX_TIME_LIMIT,
518
+ "response_url" => WFU_RESPONSE_URL,
519
+ "ajax_url" => wfu_ajaxurl(),
520
+ "wfu_pageexit_prompt" => WFU_PAGEEXIT_PROMPT,
521
+ "wfu_subdir_typedir" => WFU_SUBDIR_TYPEDIR,
522
+ "wfu_uploadprogress_mode" => WFU_VAR("WFU_UPLOADPROGRESS_MODE"),
523
+ "wfu_consent_notcompleted" => WFU_WARNING_CONSENT_NOTCOMPLETED
524
+ );
525
+ $consts_txt = "";
526
+ foreach ( $consts as $key => $val )
527
+ $consts_txt .= ( $consts_txt == "" ? "" : ";" ).wfu_plugin_encode_string($key).":".wfu_plugin_encode_string($val);
528
+
529
+ return $consts_txt;
530
  }
lib/wfu_functions.php CHANGED
@@ -1,7162 +1,7319 @@
1
- <?php
2
-
3
- /**
4
- * General Use Functions of Plugin
5
- *
6
- * This file contains general use functions of the plugin.
7
- *
8
- * @link /lib/wfu_functions.php
9
- *
10
- * @package WordPress File Upload Plugin
11
- * @subpackage Core Components
12
- * @since 2.1.2
13
- */
14
-
15
- //********************* Debug Functions ****************************************
16
-
17
- /**
18
- * Hook on plugin's functions.
19
- *
20
- * This is a very powerful function that enables almost all plugin functions to
21
- * be redeclared, either in whole or partially. Here is what it can do:
22
- *
23
- * - It can execute a hook, based on the function parameters and then
24
- * execute the original function.
25
- * - It can execute a hook, based on the function's parameters and then
26
- * return without executing the original function. This mode is like
27
- * entirely redeclaring the original function.
28
- * - It can execute a hook after execution of the original function.
29
- * - It can redeclare the function parameters or pass new variables to the
30
- * original function.
31
- *
32
- * In order to make a function redeclarable we just need to put the
33
- * following 'magic' code at the top of its function block:
34
- *
35
- * $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out);
36
- * if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v;
37
- * switch($a) { case 'R': return $out['output']; break; case 'D':
38
- * die($out['output']); }
39
- *
40
- * Then the function can be hooked through the filter wfu_debug-{__FUNCTION__}.
41
- *
42
- * The hook function takes the same parameters as the original function, plus
43
- * one, which comes first and determines the behaviour of the hook function.
44
- *
45
- * This parameter is an array having three items as follows:
46
- *
47
- * - item 'output' contains the output of the original function (if exists)
48
- * - item 'result' has no meaning as input parameter but as returning one
49
- * - item 'vars' has no meaning as input parameter but as returning one
50
- *
51
- * The hook function must return the same array as follows:
52
- *
53
- * - item 'output' must contain the hook's output
54
- * - item 'result' must be either 'X', 'R', or 'D' when the hook is executed
55
- * at the beginning of the function, as explained below. It determines how
56
- * the hook will be handled, as follows:
57
- * - If 'result' is 'X' then the result of the hook function will be
58
- * ignored and the original function will be executed afterwards.
59
- * - If 'result' is 'R' then the original function will terminate
60
- * returning the output of the hook function. So it is like having been
61
- * entirely substituted by the hook function.
62
- * - If 'result' is 'D' then the original function will die returning the
63
- * output of the hook function. This applies to ajax handlers.
64
- * In the case that the hook is executed at the end of the function, then
65
- * item 'result' must always be 'R'.
66
- * - item 'vars' is an associative array that contains any variables that the
67
- * hook wants to pass to the original function like this:
68
- * $res['output'] = array('varname1' => value1, 'varname2' => value2);
69
- * Item 'vars' can be used to redeclare the function arguments and it is a
70
- * workaround to handling arguments passed by reference.
71
- *
72
- * It is noted that the hook can be executed either before or after execution
73
- * of the original function, despite the fact that the 'magic' code is added
74
- * to the beginning of the function.
75
- *
76
- * - To execute the hook before the function a global variable with name
77
- * wfu_debug-{__FUNCTION__} must be declared.
78
- * - To execute the hook after the function a global variable with name
79
- * wfu_debug_end-{__FUNCTION__} must be declared.
80
- *
81
- * It is noted that if both of these global variables are declared, or none of
82
- * them then the hook will not work.
83
- *
84
- * Arguments passed by reference: When declaring the hook filter, all arguments
85
- * are passed by value, even if some of the original function's arguments pass
86
- * by reference. However no PHP warnings and errors will be generated due to
87
- * this difference. If the hook wants to change the value of an argument and
88
- * reflect this change to the original function, it is possible through item
89
- * 'vars' explained above. For example, if the original function passes
90
- * argument $var1 by reference (it is declared as &$var1 in the function
91
- * parameters), we cannot use the syntax $var1 = ...; inside the hook filter
92
- * but we can use the syntax $res['vars']['var1'] = ...; and this will result
93
- * $var1 in the original function to get the new value!
94
- *
95
- * @since 3.11.0
96
- *
97
- * @param string $function The function name of the original function.
98
- * @param array $args An array of parameters of the original function.
99
- * @param string $out Tt stores the output of the hook function.
100
- *
101
- * @return string Returns how the hook function will be handled ('X': hook
102
- * output must be ignored, 'R': the original function must return the
103
- * hook's output, 'D': the original function must die returning the
104
- * hook's output).
105
- */
106
- function WFU_FUNCTION_HOOK($function, $args, &$out) {
107
- // exit if plugin's debug mode is off or the hook has not been declared in
108
- // global variables;
109
- if ( WFU_VAR("WFU_DEBUG") != "ON" || !( isset($GLOBALS["wfu_debug-".$function]) xor isset($GLOBALS["wfu_debug_end-".$function]) ) ) return 'X';
110
- // exit if function name is empty or invalid
111
- if ( $function == "" || preg_replace("/[^0-9a-zA-Z_]/", "", $function) != $function ) return 'X';
112
- //if the hook has been declared in global variables with wfu_debug_end-
113
- //prefix then it will run at the end of the function
114
- if ( isset($GLOBALS["wfu_debug_end-".$function]) ) {
115
- $args_count = count($args);
116
- //if a flag (specific string) is contained in the last position of the
117
- //arguments list then do not re-execute the hook as this is the second
118
- //pass
119
- if ( $args_count > 0 && $args[$args_count - 1] === "wfu_debug_end-".$function."-second_pass" ) return 'X';
120
- else {
121
- //create an array of references to the function arguments and pass
122
- //this to call_user_func_array instead of $args; this is a
123
- //workaround to avoid PHP warnings when the original function passes
124
- //arguments by reference
125
- $args_byref = array();
126
- foreach ( $args as $key => &$arg ) $args_byref[$key] = &$arg;
127
- //add a flag (specific string) as the last argument in order to
128
- //denote that the next execution of the hook is the second pass
129
- array_push($args_byref, "wfu_debug_end-".$function."-second_pass");
130
- //call the original function and get the returned value; it will
131
- //contain the flag in the arguments, so the hook will not be
132
- //executed again and the whole script will not be put in an infinite
133
- //loop
134
- $ret = call_user_func_array($function, $args_byref);
135
- //pass the original function's output to the hook
136
- array_splice($args, 0, 0, array( array( "output" => $ret, "result" => "X", "vars" => array() ) ));
137
- /**
138
- * Hook on a Specific Function.
139
- *
140
- * This filter allows to redeclare, or change the behaviour, of the
141
- * original function $function.
142
- *
143
- * @since 3.11.0
144
- *
145
- * @param array $args Array of parameters of the original function.
146
- */
147
- $res = apply_filters_ref_array("wfu_debug-".$function, $args);
148
- if ( !is_array($res) || !isset($res["output"]) || !isset($res["result"]) ) $res = array( "output" => $ret, "result" => "R" );
149
- if ( $res["result"] != 'R' ) $res["result"] = 'R';
150
- if ( isset($res["vars"]) && !is_array($res["vars"]) ) $res["vars"] = array();
151
- $out = $res;
152
- return $res["result"];
153
- }
154
- }
155
- else {
156
- // prepare the arguments for the hook
157
- array_splice($args, 0, 0, array( array( "output" => "", "result" => "X", "vars" => array() ) ));
158
- /** This hook is decribed above. */
159
- $res = apply_filters_ref_array("wfu_debug-".$function, $args);
160
- // exit if $res is invalid
161
- if ( !is_array($res) || !isset($res["output"]) || !isset($res["result"]) ) $res = array( "output" => "", "result" => "X" );
162
- if ( $res["result"] != 'X' && $res["result"] != 'R' && $res["result"] != 'D' ) $res["result"] = 'X';
163
- if ( isset($res["vars"]) && !is_array($res["vars"]) ) $res["vars"] = array();
164
- $out = $res;
165
- // if result is 'X' then the caller must ignore the hook
166
- // if result is 'R' then the caller must return the hook's output
167
- // if result is 'D' then the caller must die returning the hook's output
168
- return $res["result"];
169
- }
170
- }
171
-
172
- //********************* String Functions ***************************************
173
-
174
- /**
175
- * Sanitize Filename.
176
- *
177
- * This function sanitizes filename so that it is compatible with most file
178
- * systems. Invalid non-latin characters will be converted into dashes.
179
- *
180
- * @since 2.1.2
181
- *
182
- * @param string $filename The file name.
183
- *
184
- * @return string The sanitized file name.
185
- */
186
- function wfu_upload_plugin_clean($filename) {
187
- $clean = sanitize_file_name($filename);
188
- if ( WFU_VAR("WFU_SANITIZE_FILENAME_MODE") != "loose" ) {
189
- $name = wfu_filename($clean);
190
- $ext = wfu_fileext($clean);
191
- if ( WFU_VAR("WFU_SANITIZE_FILENAME_DOTS") == "true" ) $name_search = array ( '@[^a-zA-Z0-9_]@' );
192
- else $name_search = array ( '@[^a-zA-Z0-9._]@' );
193
- $ext_search = array ( '@[^a-zA-Z0-9._]@' );
194
- $replace = array ( '-' );
195
- $clean_name = preg_replace($name_search, $replace, remove_accents($name));
196
- $clean_ext = preg_replace($ext_search, $replace, remove_accents($ext));
197
- $clean = $clean_name.".".$clean_ext;
198
- }
199
-
200
- return $clean;
201
- }
202
-
203
- /**
204
- * Wildcard Conversion Callback.
205
- *
206
- * This function is a callback used in a preg_replace_callback() function to
207
- * convert wildcard syntax to natural expression.
208
- *
209
- * @since 3.9.0
210
- *
211
- * @global array $wfu_preg_replace_callback_var An array with matches.
212
- *
213
- * @param array $matches An array of matches of preg_replace_callback().
214
- *
215
- * @return string The result of the callback processing the matches.
216
- */
217
- function _wildcard_to_preg_preg_replace_callback($matches) {
218
- global $wfu_preg_replace_callback_var;
219
- array_push($wfu_preg_replace_callback_var, $matches[0]);
220
- $key = count($wfu_preg_replace_callback_var) - 1;
221
- return "[".$key."]";
222
- }
223
-
224
- /**
225
- * Wildcard To Natural Expression Conversion.
226
- *
227
- * This function converts wildcard syntax of a pattern to natural expression.
228
- *
229
- * @since 2.1.2
230
- *
231
- * @global array $wfu_preg_replace_callback_var An array with matches.
232
- *
233
- * @param string $pattern The pattern to convert.
234
- * @param bool $strict Optional. Strict matching. If true, dot symbols (.) will
235
- * not be matched.
236
- *
237
- * @return The converted natural expression pattern.
238
- */
239
- function wfu_upload_plugin_wildcard_to_preg($pattern, $strict = false) {
240
- global $wfu_preg_replace_callback_var;
241
- $wfu_preg_replace_callback_var = array();
242
- $pattern = preg_replace_callback("/\[(.*?)\]/", "_wildcard_to_preg_preg_replace_callback", $pattern);
243
- if ( !$strict ) $pattern = '/^' . str_replace(array('\*', '\?', '\[', '\]'), array('.*', '.', '[', ']'), preg_quote($pattern)) . '$/is';
244
- else $pattern = '/^' . str_replace(array('\*', '\?', '\[', '\]'), array('[^.]*', '.', '[', ']'), preg_quote($pattern)) . '$/is';
245
- foreach ($wfu_preg_replace_callback_var as $key => $match)
246
- $pattern = str_replace("[".$key."]", $match, $pattern);
247
- return $pattern;
248
- }
249
-
250
- /**
251
- * Wildcard To MySQL Natural Expression Conversion.
252
- *
253
- * This function converts wildcard syntax of a pattern to MySQL natural
254
- * expression.
255
- *
256
- * @since 3.2.1
257
- *
258
- * @redeclarable
259
- *
260
- * @param string $pattern The pattern to convert.
261
- *
262
- * @return The converted MySQL natural expression pattern.
263
- */
264
- function wfu_upload_plugin_wildcard_to_mysqlregexp($pattern) {
265
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
266
- if ( substr($pattern, 0, 6) == "regex:" ) return str_replace("\\", "\\\\", substr($pattern, 6));
267
- else return str_replace("\\", "\\\\", '^'.str_replace(array('\*', '\?', '\[', '\]'), array('.*', '.', '[', ']'), preg_quote($pattern)).'$');
268
- }
269
-
270
- /**
271
- * Match String With Pattern.
272
- *
273
- * This function checks if a specific string matches with a pattern.
274
- *
275
- * @since 2.1.2
276
- *
277
- * @param string $pattern The pattern to match.
278
- * @param string $str The string to match.
279
- * @param bool $strict Defines whether strict mode will be used. In strict mode
280
- * dot symbols (.) are not considered as normal characters and are not
281
- * matched with preg * symbol.
282
- *
283
- * @return bool True if there is a match, false otherwise.
284
- */
285
- function wfu_upload_plugin_wildcard_match($pattern, $str, $strict = false) {
286
- $pattern = wfu_upload_plugin_wildcard_to_preg($pattern, $strict);
287
- return preg_match($pattern, $str);
288
- }
289
-
290
- /**
291
- * Convert String to Hex.
292
- *
293
- * This function converts every character of a string into a 2-byte hex
294
- * representation.
295
- *
296
- * @since 2.1.2
297
- *
298
- * @param string $string The string to convert.
299
- *
300
- * @return string The converted hex string.
301
- */
302
- function wfu_plugin_encode_string($string) {
303
- $array = unpack('H*', $string);
304
- return $array[1];
305
-
306
- $array = unpack('C*', $string);
307
- $new_string = "";
308
- for ($i = 1; $i <= count($array); $i ++) {
309
- $new_string .= sprintf("%02X", $array[$i]);
310
- }
311
- return $new_string;
312
- }
313
-
314
- /**
315
- * Convert Hex to String.
316
- *
317
- * This function converts a hex string into a normal ASCII string.
318
- *
319
- * @since 2.1.2
320
- *
321
- * @param string $string The hex string to convert.
322
- *
323
- * @return string The converted ASCII string.
324
- */
325
- function wfu_plugin_decode_string($string) {
326
- return pack('H*', $string);
327
-
328
- $new_string = "";
329
- for ($i = 0; $i < strlen($string); $i += 2 ) {
330
- $new_string .= sprintf("%c", hexdec(substr($string, $i ,2)));
331
- }
332
- return $new_string;
333
- }
334
-
335
- /**
336
- * Create a Random String.
337
- *
338
- * This function creates a random string composing of latin letters and numbers.
339
- *
340
- * @since 2.1.2
341
- *
342
- * @param integer $len The length of the string.
343
- * @param bool $hex True if a hex string must be generated.
344
- *
345
- * @return string The random string.
346
- */
347
- function wfu_create_random_string($len, $hex = false) {
348
- $base1 = 'ABCDEFGHKLMNOPQRSTWXYZabcdefghjkmnpqrstwxyz123456789';
349
- $base2 = 'ABCDEFGHKLMNOPQRSTWXYZabcdefghjkmnpqrstwxyz123456789';
350
- if ( $hex ) {
351
- $base1 = 'abcdef123456789';
352
- $base2 = 'abcdef0123456789';
353
- }
354
- $max1 = strlen($base1) - 1;
355
- $max2 = strlen($base2) - 1;
356
- $activatecode = '';
357
- if ( WFU_VAR("WFU_ALTERNATIVE_RANDOMIZER") != "true" )
358
- mt_srand((double)microtime()*1000000);
359
- else mt_srand((double)substr(uniqid("", true), 15));
360
- $is_first = true;
361
- while (strlen($activatecode) < $len) {
362
- if ( $is_first ) {
363
- $activatecode .= $base1[mt_rand(0, $max1)];
364
- $is_first = false;
365
- }
366
- else $activatecode .= $base2[mt_rand(0, $max2)];
367
- }
368
- return $activatecode;
369
- }
370
-
371
- /**
372
- * Join Two or More Strings.
373
- *
374
- * This function joins one or more strings. The strings are passed in the
375
- * function as 2nd, 3rd, 4rth and so on parameters.
376
- *
377
- * @since 2.1.2
378
- *
379
- * @param string $delimeter The delimeter to use to join the strings.
380
- *
381
- * @return string The resulted joined string.
382
- */
383
- function wfu_join_strings($delimeter) {
384
- $arr = func_get_args();
385
- unset($arr[0]);
386
- foreach ($arr as $key => $item)
387
- if ( $item == "" ) unset($arr[$key]);
388
- return join($delimeter, $arr);
389
- }
390
-
391
- /**
392
- * Create a String of Zeros.
393
- *
394
- * This function creates a string filled with zeros. It is designed to be fast
395
- * even when the length of the string is large.
396
- *
397
- * @since 2.1.2
398
- *
399
- * @param integer $size The size of the string.
400
- *
401
- * @return string The resulted string.
402
- */
403
- function wfu_create_string($size) {
404
- $piece = str_repeat("0", 1024);
405
- $str = "";
406
- $reps = $size / 1024;
407
- $rem = $size - 1024 * $reps;
408
- for ( $i = 0; $i < $reps; $i++ ) $str .= $piece;
409
- $str .= substr($piece, 0, $rem);
410
- return $str;
411
- }
412
-
413
- /**
414
- * Prepare String for HTML Output.
415
- *
416
- * This function converts newline characters into <br> tags and tabs/spaces into
417
- * &nbsp; entities, so that they can be property shown in HTML output.
418
- *
419
- * @since 2.7.1
420
- *
421
- * @param string $output The string to be sent to output.
422
- *
423
- * @return string The converted HTML ready string.
424
- */
425
- function wfu_html_output($output) {
426
- $output = str_replace(array("\r\n", "\r", "\n"), "<br/>", $output);
427
- return str_replace(array("\t", " "), "&nbsp;", $output);
428
- }
429
-
430
- /**
431
- * Sanitize a Code.
432
- *
433
- * This function sanitizes a code. A code must only contain latin letters and
434
- * numbers.
435
- *
436
- * @since 3.0.0
437
- *
438
- * @param string $code The code to sanitize.
439
- *
440
- * @return string The sanitized code.
441
- */
442
- function wfu_sanitize_code($code) {
443
- return preg_replace("/[^A-Za-z0-9]/", "", $code);
444
- }
445
-
446
- /**
447
- * Sanitize an Integer.
448
- *
449
- * This function sanitizes an integer (passed as string). An integer must only
450
- * contain numbers, plus (+) and minus (-) symbols.
451
- *
452
- * @since 3.1.0
453
- *
454
- * @param string $code The integer to sanitize passed as string.
455
- *
456
- * @return string The sanitized integer returned as string.
457
- */
458
- function wfu_sanitize_int($code) {
459
- return preg_replace("/[^0-9+\-]/", "", $code);
460
- }
461
-
462
- /**
463
- * Sanitize a Float.
464
- *
465
- * This function sanitizes a float (passed as string). A float must only contain
466
- * numbers, plus (+), minus (-), dot (.) and comma (,) symbols.
467
- *
468
- * @since 4.3.3
469
- *
470
- * @param string $code The float to sanitize passed as string.
471
- *
472
- * @return string The sanitized float returned as string.
473
- */
474
- function wfu_sanitize_float($code) {
475
- return preg_replace("/[^0-9+\-\.,]/", "", $code);
476
- }
477
-
478
- /**
479
- * Sanitize a Color Value.
480
- *
481
- * This function sanitizes a color value. A color value must only contain
482
- * characters a-f or A-F, numbers, number sign (#) and comma (,) symbols.
483
- *
484
- * @since 4.3.3
485
- *
486
- * @param string $code The color value to sanitize.
487
- *
488
- * @return string The sanitized color value.
489
- */
490
- function wfu_sanitize_colors($code) {
491
- return preg_replace("/[^A-Fa-f0-9#,]/", "", $code);
492
- }
493
-
494
- /**
495
- * Sanitize a Tag.
496
- *
497
- * This function sanitizes a tag. A tag must only contain latin characters,
498
- * numbers and underscore (_) symbols.
499
- *
500
- * @since 3.1.0
501
- *
502
- * @param string $code The tag to sanitize.
503
- *
504
- * @return string The sanitized tag.
505
- */
506
- function wfu_sanitize_tag($code) {
507
- return preg_replace("/[^A-Za-z0-9_]/", "", $code);
508
- }
509
-
510
- /**
511
- * Sanitize a URL.
512
- *
513
- * This function sanitizes a URL.
514
- *
515
- * @since 3.11.0
516
- *
517
- * @param string $url The URL to sanitize.
518
- *
519
- * @return string The sanitized URL.
520
- */
521
- function wfu_sanitize_url($url) {
522
- return filter_var(strip_tags($url), FILTER_SANITIZE_URL);
523
- }
524
-
525
- /**
526
- * Sanitize a List of URL.
527
- *
528
- * This function sanitizes a list of URLs.
529
- *
530
- * @since 3.11.0
531
- *
532
- * @param string $urls The URLs to sanitize.
533
- * @param string $separator The delimeter character of the URLs.
534
- *
535
- * @return string The sanitized URLs.
536
- */
537
- function wfu_sanitize_urls($urls, $separator) {
538
- $urls_arr = explode($separator, $urls);
539
- foreach( $urls_arr as &$url ) $url = wfu_sanitize_url($url);
540
- return implode($separator, $urls_arr);
541
- }
542
-
543
- /**
544
- * Sanitize a Shortcode.
545
- *
546
- * This function sanitizes a shortcode, that is sanitizes all its attributes.
547
- *
548
- * @since 4.3.3
549
- *
550
- * @param string $shortcode The shortcode to sanitize.
551
- * @param string $shortcode_tag The shortcode tag.
552
- *
553
- * @return string The sanitized shortcode.
554
- */
555
- function wfu_sanitize_shortcode($shortcode, $shortcode_tag) {
556
- $attrs = wfu_shortcode_string_to_array($shortcode);
557
- $sanitized_attrs = wfu_sanitize_shortcode_array($attrs, $shortcode_tag);
558
- //reconstruct sanitized shortcode string from array
559
- $sanitized_shortcode = "";
560
- foreach ( $sanitized_attrs as $attr => $value )
561
- $sanitized_shortcode .= ( $sanitized_shortcode == "" ? "" : " " ).$attr.'="'.$value.'"';
562
-
563
- return $sanitized_shortcode;
564
- }
565
-
566
- /**
567
- * Sanitize Shortcode Attributes.
568
- *
569
- * This function sanitizes an array of shortcode attributes.
570
- *
571
- * @since 4.5.1
572
- *
573
- * @param array $attrs An array of shortcode attributes to sanitize.
574
- * @param string $shortcode_tag The shortcode tag.
575
- *
576
- * @return array The sanitized array of shortcode attributes.
577
- */
578
- function wfu_sanitize_shortcode_array($attrs, $shortcode_tag) {
579
- $sanitized_attrs = array();
580
- if ( $shortcode_tag == 'wordpress_file_upload' ) $defs = wfu_attribute_definitions();
581
- else $defs = wfu_browser_attribute_definitions();
582
- // get validator types for defs
583
- $def_validators = array();
584
- foreach ( $defs as $def ) $def_validators[$def['attribute']] = $def['validator'];
585
- // sanitize each attribute
586
- foreach ( $attrs as $attr => $value ) {
587
- //first sanitize the attribute name
588
- $sanitized = sanitize_text_field($attr);
589
- //continue only for attributes that sanitization did not crop any
590
- //characters
591
- if ( $sanitized == $attr && $attr != "" ) {
592
- //flatten attributes that have many occurencies
593
- $flat = preg_replace("/^(.*?)[0-9]*$/", "$1", $attr);
594
- //get validator type
595
- $validator = "text";
596
- if ( isset($def_validators[$flat]) ) $validator = $def_validators[$flat];
597
- //sanitize value based on validator type
598
- $new_value = $value;
599
- switch( $validator ) {
600
- case "text":
601
- $new_value = wp_strip_all_tags($value);
602
- break;
603
- case "integer":
604
- $new_value = wfu_sanitize_int($value);
605
- break;
606
- case "float":
607
- $new_value = wfu_sanitize_float($value);
608
- break;
609
- case "path":
610
- $new_value = wp_strip_all_tags($value);
611
- break;
612
- case "link":
613
- $new_value = wp_strip_all_tags($value);
614
- break;
615
- case "emailheaders":
616
- if ( strpos(strtolower($value), "<script") !== false ) $new_value = "";
617
- break;
618
- case "emailsubject":
619
- if ( strpos(strtolower($value), "<script") !== false ) $new_value = "";
620
- break;
621
- case "emailbody":
622
- if ( strpos(strtolower($value), "<script") !== false ) $new_value = "";
623
- break;
624
- case "colors":
625
- $new_value = wfu_sanitize_colors($value);
626
- break;
627
- case "css":
628
- $new_value = wp_strip_all_tags($value);
629
- break;
630
- case "datetime":
631
- $new_value = wp_strip_all_tags($value);
632
- break;
633
- case "pattern":
634
- if ( substr_count($value, "'") > 0 && substr_count($value, "'") > substr_count($value, "\\'") ) $new_value = "";
635
- break;
636
- default:
637
- $new_value = wp_strip_all_tags($value);
638
- }
639
- /**
640
- * Custom Shortcode Sanitization.
641
- *
642
- * This filter allows custom actions to change the sanitization
643
- * result of shortcode attributes.
644
- *
645
- * @since 4.3.3
646
- *
647
- * @param string $new_value New sanitized value of the attribute.
648
- * @param string $attr The attribute name.
649
- * @param string $validator The type of attribute used to determine
650
- * the type of validator to use.
651
- * @param string $value The initial value of the attribute.
652
- */
653
- $new_value = apply_filters("_wfu_sanitize_shortcode", $new_value, $attr, $validator, $value);
654
- $sanitized_attrs[$attr] = $new_value;
655
- }
656
- }
657
-
658
- return $sanitized_attrs;
659
- }
660
-
661
- /**
662
- * Escape a Variable.
663
- *
664
- * This function escapes (adds backslashes before characters that need to be
665
- * escaped) a variable, even if it is an array of unlimited depth.
666
- *
667
- * @since 3.3.0
668
- *
669
- * @param mixed $value The variable to be escaped.
670
- *
671
- * @return mixed The escaped variable.
672
- */
673
- function wfu_slash( $value ) {
674
- if ( is_array( $value ) ) {
675
- foreach ( $value as $k => $v ) {
676
- if ( is_array( $v ) ) {
677
- $value[$k] = wfu_slash( $v );
678
- }
679
- else {
680
- $value[$k] = addslashes( $v );
681
- }
682
- }
683
- }
684
- else {
685
- $value = addslashes( $value );
686
- }
687
-
688
- return $value;
689
- }
690
-
691
- /**
692
- * Generate a Global Short-Life Token.
693
- *
694
- * This function generates a short-life token that is stored in Wordpress
695
- * Options and has a global scope (is accessible by all users).
696
- *
697
- * @since 3.5.0
698
- *
699
- * @param integer $timeout The life of the token in seconds.
700
- *
701
- * @return string The token.
702
- */
703
- function wfu_generate_global_short_token($timeout) {
704
- $token = wfu_create_random_string(16);
705
- $expire = time() + (int)$timeout;
706
- update_option('wfu_gst_'.$token, $expire);
707
- return $token;
708
- }
709
-
710
- /**
711
- * Verify a Global Short-Life Token.
712
- *
713
- * This function verifies that a global short-life token exists and it not
714
- * expired. After verification the token is removed.
715
- *
716
- * @since 3.5.0
717
- *
718
- * @param string $token The token to verify.
719
- *
720
- * @return bool True if verification was successful, false otherwise.
721
- */
722
- function wfu_verify_global_short_token($token) {
723
- $timeout = get_option('wfu_gst_'.$token);
724
- if ( $timeout === false ) return false;
725
- delete_option('wfu_gst_'.$token);
726
- return ( $timeout > time() );
727
- }
728
-
729
- /**
730
- * Generate a User Short-Life Token.
731
- *
732
- * This function generates a short-life token that is stored in a user's User
733
- * Space and has a user scope (is accessible only by this user).
734
- *
735
- * @since 4.9.0
736
- *
737
- * @param integer $timeout The life of the token in seconds.
738
- *
739
- * @return string The token.
740
- */
741
- function wfu_generate_user_short_token($timeout) {
742
- $token = wfu_create_random_string(16);
743
- $expire = time() + (int)$timeout;
744
- WFU_USVAR_store('wfu_ust_'.$token, $expire);
745
- return $token;
746
- }
747
-
748
- /**
749
- * Verify a User Short-Life Token.
750
- *
751
- * This function verifies that a user short-life token exists and it not
752
- * expired. After verification the token is removed.
753
- *
754
- * @since 4.9.0
755
- *
756
- * @param string $token The token to verify.
757
- *
758
- * @return bool True if verification was successful, false otherwise.
759
- */
760
- function wfu_verify_user_short_token($token) {
761
- if ( !WFU_USVAR_exists('wfu_ust_'.$token) ) return false;
762
- $timeout = WFU_USVAR('wfu_ust_'.$token);
763
- WFU_USVAR_unset('wfu_ust_'.$token);
764
- return ( $timeout > time() );
765
- }
766
-
767
- //********************* Array Functions ****************************************
768
-
769
- /**
770
- * Encode Array to String.
771
- *
772
- * This function converts an array to a JSON string and then encodes it to its
773
- * hex representation.
774
- *
775
- * @since 2.1.2
776
- *
777
- * @param array $arr The array to encode.
778
- *
779
- * @return string The encoded hex string.
780
- */
781
- function wfu_encode_array_to_string($arr) {
782
- $arr_str = json_encode($arr);
783
- $arr_str = wfu_plugin_encode_string($arr_str);
784
- return $arr_str;
785
- }
786
-
787
- /**
788
- * Decode Array from String.
789
- *
790
- * This function converts a hex string to its ASCII representation, which is a
791
- * JSON string and then decodes it to an array.
792
- *
793
- * @since 2.1.2
794
- *
795
- * @param string $arr_str The encoded hex string to decode.
796
- *
797
- * @return array The decoded array.
798
- */
799
- function wfu_decode_array_from_string($arr_str) {
800
- $arr_str = wfu_plugin_decode_string($arr_str);
801
- $arr = json_decode($arr_str, true);
802
- return $arr;
803
- }
804
-
805
- /**
806
- * Decode HTML Entities in Array.
807
- *
808
- * This function decodes HTML entities found in array values into their special
809
- * characters. It is useful when reading a shortcode array.
810
- *
811
- * @since 2.1.2
812
- *
813
- * @param array $source The source array.
814
- *
815
- * @return array The decoded array.
816
- */
817
- function wfu_plugin_parse_array($source) {
818
- $keys = array_keys($source);
819
- $new_arr = array();
820
- for ($i = 0; $i < count($keys); $i ++)
821
- $new_arr[$keys[$i]] = wp_specialchars_decode($source[$keys[$i]]);
822
- return $new_arr;
823
- }
824
-
825
- /**
826
- * Encode Special Characters in Array.
827
- *
828
- * This function converts special characters found in array values into HTML
829
- * entities.
830
- *
831
- * @since 2.1.2
832
- *
833
- * @param array $arr The source array.
834
- *
835
- * @return array The encoded array.
836
- */
837
- function wfu_safe_array($arr) {
838
- return array_map("htmlspecialchars", $arr);
839
- }
840
-
841
- /**
842
- * Remove Nulls from Array.
843
- *
844
- * This function removes null items from array.
845
- *
846
- * @since 2.1.2
847
- *
848
- * @param array $arr The source array.
849
- *
850
- * @return array The cleaned array.
851
- */
852
- function wfu_array_remove_nulls(&$arr) {
853
- foreach ( $arr as $key => $arri )
854
- if ( $arri == null )
855
- array_splice($arr, $key, 1);
856
- }
857
-
858
- /**
859
- * Sanitize a Variable.
860
- *
861
- * This function sanitizes (converts special characters into HTML entities) a
862
- * variable. If the variable is an array it will sanitize all elements
863
- * recursively regardless of array depth. If the variable is not of an accepted
864
- * type then its type will be returned.
865
- *
866
- * @since 2.4.4
867
- *
868
- * @param mixed $var The variable to sanitize.
869
- *
870
- * @return mixed The sanitized variable.
871
- */
872
- function wfu_sanitize($var) {
873
- $typ = gettype($var);
874
- if ( $typ == "boolean" || $typ == "integer" || $typ == "double" || $typ == "resource" || $typ == "NULL" )
875
- return $var;
876
- elseif ( $typ == "string" )
877
- return htmlspecialchars($var);
878
- elseif ( $typ == "array" || $typ == "object" ) {
879
- foreach ( $var as &$item ) $item = wfu_sanitize($item);
880
- return $var;
881
- }
882
- else
883
- return $typ;
884
- }
885
-
886
- /**
887
- * Mask a Shortcode.
888
- *
889
- * This function is part of a process to safely parse a shortcode string into an
890
- * associative array. It replaces all attribute values by tokens, so that it is
891
- * easier and safer for the process to separate the attributes.
892
- *
893
- * @since 2.2.1
894
- *
895
- * @param string $contents The shortcode.
896
- * @param string $token The token that replaces the shortcode attribute values.
897
- *
898
- * @return array An array of converted attributes.
899
- */
900
- function _wfu_preg_replace_callback_alt($contents, $token) {
901
- $in_block = false;
902
- $prev_pos = 0;
903
- $new_contents = '';
904
- $ret['items'] = array();
905
- $ret['tokens'] = array();
906
- $ii = 0;
907
- while ( ($pos = strpos($contents, '"', $prev_pos)) !== false ) {
908
- if ( !$in_block ) {
909
- $new_contents .= substr($contents, $prev_pos, $pos - $prev_pos + 1);
910
- $in_block = true;
911
- }
912
- else {
913
- $ret['items'][$ii] = substr($contents, $prev_pos, $pos - $prev_pos);
914
- $ret['tokens'][$ii] = $token.sprintf('%03d', $ii);
915
- $new_contents .= $token.sprintf('%03d', $ii).'"';
916
- $ii ++;
917
- $in_block = false;
918
- }
919
- $prev_pos = $pos + 1;
920
- }
921
- if ( $in_block ) {
922
- $ret['items'][$ii] = substr($contents, $prev_pos);
923
- $ret['tokens'][$ii] = $token.sprintf('%03d', $ii);
924
- $new_contents .= $token.sprintf('%03d', $ii).'"';
925
- }
926
- else
927
- $new_contents .= substr($contents, $prev_pos);
928
- $ret['contents'] = $new_contents;
929
- return $ret;
930
- }
931
-
932
- /**
933
- * Parse a Shortcode.
934
- *
935
- * This function safely parses a shortcode string into an associative array.
936
- *
937
- * @since 2.1.3
938
- *
939
- * @param string $shortcode The shortcode.
940
- *
941
- * @return array The parsed shortcode as an associative array of attributes.
942
- */
943
- function wfu_shortcode_string_to_array($shortcode) {
944
- $i = 0;
945
- $m1 = array();
946
- $m2 = array();
947
- //for some reason preg_replace_callback does not work in all cases, so it has been replaced by a similar custom inline routine
948
- // $mm = preg_replace_callback('/"([^"]*)"/', function ($matches) use(&$i, &$m1, &$m2) {array_push($m1, $matches[1]); array_push($m2, "attr".$i); return "attr".$i++;}, $shortcode);
949
- $ret = _wfu_preg_replace_callback_alt($shortcode, "attr");
950
- $mm = $ret['contents'];
951
- $m1 = $ret['items'];
952
- $m2 = $ret['tokens'];
953
- $arr = explode(" ", $mm);
954
- $attrs = array();
955
- foreach ( $arr as $attr ) {
956
- if ( trim($attr) != "" ) {
957
- $attr_arr = explode("=", $attr, 2);
958
- $key = "";
959
- if ( count($attr_arr) > 0 ) $key = $attr_arr[0];
960
- $val = "";
961
- if ( count($attr_arr) > 1 ) $val = $attr_arr[1];
962
- if ( trim($key) != "" ) $attrs[trim($key)] = str_replace('"', '', $val);
963
- }
964
- }
965
- $attrs2 = str_replace($m2, $m1, $attrs);
966
- return $attrs2;
967
- }
968
-
969
- /**
970
- * Compare Two Strings in Ascending Order.
971
- *
972
- * This function returns the comparison result of two strings. It is part of an
973
- * array sorting mechanism.
974
- *
975
- * @since 3.8.5
976
- *
977
- * @param string $a The first string.
978
- * @param string $b The second string.
979
- *
980
- * @return int Returns < 0 if a is less than b; > 0 if a is greater than b
981
- * and 0 if they are equal.
982
- */
983
- function wfu_array_sort_function_string_asc($a, $b) {
984
- return strcmp(strtolower($a), strtolower($b));
985
- }
986
-
987
- /**
988
- * Compare Two Strings Having a Second Property in Ascending Order.
989
- *
990
- * This function returns the comparison result of two strings. If the strings
991
- * are equal then comparison will be done based on a second property (id0) of
992
- * the strings, so that 0 is never returned. It is part of an array sorting
993
- * mechanism.
994
- *
995
- * @since 3.8.5
996
- *
997
- * @param array $a The first string. It is passed as an array. 'value' item of
998
- * the array is the string. 'id0' item is the second property.
999
- * @param array $b The second string. It is passed as an array. 'value' item of
1000
- * the array is the string. 'id0' item is the second property.
1001
- *
1002
- * @return int Returns < 0 if a is less than b; > 0 if a is greater.
1003
- */
1004
- function wfu_array_sort_function_string_asc_with_id0($a, $b) {
1005
- $cmp = strcmp(strtolower($a["value"]), strtolower($b["value"]));
1006
- if ( $cmp == 0 ) $cmp = ( (int)$a["id0"] < (int)$b["id0"] ? -1 : 1 );
1007
- return $cmp;
1008
- }
1009
-
1010
- /**
1011
- * Compare Two Strings in Descending Order.
1012
- *
1013
- * This function returns the negstive of the comparison result of two strings.
1014
- * It is part of an array sorting mechanism.
1015
- *
1016
- * @since 3.8.5
1017
- *
1018
- * @param string $a The first string.
1019
- * @param string $b The second string.
1020
- *
1021
- * @return int Returns > 0 if a is less than b; < 0 if a is greater than b
1022
- * and 0 if they are equal.
1023
- */
1024
- function wfu_array_sort_function_string_desc($a, $b) {
1025
- return -strcmp(strtolower($a), strtolower($b));
1026
- }
1027
-
1028
- /**
1029
- * Compare Two Strings Having a Second Property in Descending Order.
1030
- *
1031
- * This function returns the negative of the comparison result of two strings.
1032
- * If the strings are equal then comparison will be done based on a second
1033
- * property (id0) of the strings, so that 0 is never returned. It is part of an
1034
- * array sorting mechanism.
1035
- *
1036
- * @since 3.8.5
1037
- *
1038
- * @param array $a The first string. It is passed as an array. 'value' item of
1039
- * the array is the string. 'id0' item is the second property.
1040
- * @param array $b The second string. It is passed as an array. 'value' item of
1041
- * the array is the string. 'id0' item is the second property.
1042
- *
1043
- * @return int Returns > 0 if a is less than b; < 0 if a is greater.
1044
- */
1045
- function wfu_array_sort_function_string_desc_with_id0($a, $b) {
1046
- $cmp = strcmp(strtolower($a["value"]), strtolower($b["value"]));
1047
- if ( $cmp == 0 ) $cmp = ( (int)$a["id0"] < (int)$b["id0"] ? -1 : 1 );
1048
- return -$cmp;
1049
- }
1050
-
1051
- /**
1052
- * Compare Two Numbers in Ascending Order.
1053
- *
1054
- * This function returns the comparison result of two numbers. It is part of an
1055
- * array sorting mechanism.
1056
- *
1057
- * @since 3.8.5
1058
- *
1059
- * @param int|float|double $a The first number.
1060
- * @param int|float|double $b The second number.
1061
- *
1062
- * @return int Returns -1 if a is less than b; 1 if a is greater than b
1063
- * and 0 if they are equal.
1064
- */
1065
- function wfu_array_sort_function_numeric_asc($a, $b) {
1066
- $aa = (double)$a;
1067
- $bb = (double)$b;
1068
- if ( $aa < $bb ) return -1;
1069
- elseif ( $aa > $bb ) return 1;
1070
- else return 0;
1071
- }
1072
-
1073
- /**
1074
- * Compare Two Numbers Having a Second Property in Ascending Order.
1075
- *
1076
- * This function returns the comparison result of two numbers. If the numbers
1077
- * are equal then comparison will be done based on a second property (id0) of
1078
- * the numbers, so that 0 is never returned. It is part of an array sorting
1079
- * mechanism.
1080
- *
1081
- * @since 3.8.5
1082
- *
1083
- * @param array $a The first number. It is passed as an array. 'value' item of
1084
- * the array is the number. 'id0' item is the second property.
1085
- * @param array $b The second number. It is passed as an array. 'value' item of
1086
- * the array is the number. 'id0' item is the second property.
1087
- *
1088
- * @return int Returns -1 if a is less than b; 1 if a is greater.
1089
- */
1090
- function wfu_array_sort_function_numeric_asc_with_id0($a, $b) {
1091
- $aa = (double)$a["value"];
1092
- $bb = (double)$b["value"];
1093
- if ( $aa < $bb ) return -1;
1094
- elseif ( $aa > $bb ) return 1;
1095
- elseif ( (int)$a["id0"] < (int)$b["id0"] ) return -1;
1096
- else return 1;
1097
- }
1098
-
1099
- /**
1100
- * Compare Two Numbers in Descending Order.
1101
- *
1102
- * This function returns the negstive of the comparison result of two numbers.
1103
- * It is part of an array sorting mechanism.
1104
- *
1105
- * @since 3.8.5
1106
- *
1107
- * @param int|float|number $a The first number.
1108
- * @param int|float|number $b The second number.
1109
- *
1110
- * @return int Returns 1 if a is less than b; -1 if a is greater than b
1111
- * and 0 if they are equal.
1112
- */
1113
- function wfu_array_sort_function_numeric_desc($a, $b) {
1114
- $aa = (double)$a;
1115
- $bb = (double)$b;
1116
- if ( $aa > $bb ) return -1;
1117
- elseif ( $aa < $bb ) return 1;
1118
- else return 0;
1119
- }
1120
-
1121
- /**
1122
- * Compare Two Numbers Having a Second Property in Descending Order.
1123
- *
1124
- * This function returns the negative of the comparison result of two numbers.
1125
- * If the numbers are equal then comparison will be done based on a second
1126
- * property (id0) of the numbers, so that 0 is never returned. It is part of an
1127
- * array sorting mechanism.
1128
- *
1129
- * @since 3.8.5
1130
- *
1131
- * @param array $a The first number. It is passed as an array. 'value' item of
1132
- * the array is the number. 'id0' item is the second property.
1133
- * @param array $b The second number. It is passed as an array. 'value' item of
1134
- * the array is the number. 'id0' item is the second property.
1135
- *
1136
- * @return int Returns 1 if a is less than b; -1 if a is greater.
1137
- */
1138
- function wfu_array_sort_function_numeric_desc_with_id0($a, $b) {
1139
- $aa = (double)$a["value"];
1140
- $bb = (double)$b["value"];
1141
- if ( $aa > $bb ) return -1;
1142
- elseif ( $aa < $bb ) return 1;
1143
- elseif ( (int)$a["id0"] > (int)$b["id0"] ) return -1;
1144
- else return 1;
1145
- }
1146
-
1147
- /**
1148
- * Sort an Array Based on Key.
1149
- *
1150
- * This function sorts an array based on a key. It is used to sort a tabular
1151
- * list based on a column. Every item of the array is another associative array
1152
- * representing a row of the table. The key of every item is the column of the
1153
- * table.
1154
- *
1155
- * @since 2.2.1
1156
- *
1157
- * @param array $array. The array to sort.
1158
- * @param string $on. The sorting column name. If it is preceeded by 's:' it
1159
- * will be sorted as string. If it is preceeded by 'n:' it will be sorted
1160
- * as numeric.
1161
- * @param int $order Optional. The sorting order. It can be SORT_ASC or
1162
- * SORT_DESC.
1163
- * @param bool $with_id0 Optional. A secord property will be used for sorting.
1164
- *
1165
- * @return array The sorted array.
1166
- */
1167
- function wfu_array_sort($array, $on, $order = SORT_ASC, $with_id0 = false) {
1168
- $new_array = array();
1169
- $sortable_array = array();
1170
-
1171
- $pos = strpos($on, ":");
1172
- if ( $pos !== false ) {
1173
- $sorttype = substr($on, $pos + 1);
1174
- if ( $sorttype == "" ) $sorttype = "s";
1175
- $on = substr($on, 0, $pos);
1176
- }
1177
- else $sorttype = "s";
1178
-
1179
- if (count($array) > 0) {
1180
- foreach ($array as $k => $v) {
1181
- if (is_array($v)) {
1182
- foreach ($v as $k2 => $v2) {
1183
- if ($k2 == $on) {
1184
- $sortable_array[$k] = ( $with_id0 ? array( "id0" => $v["id0"], "value" => $v2 ) : $v2 );
1185
- }
1186
- }
1187
- } else {
1188
- $sortable_array[$k] = $v;
1189
- $with_id0 = false;
1190
- }
1191
- }
1192
-
1193
- uasort($sortable_array, "wfu_array_sort_function_".( $sorttype == "n" ? "numeric" : "string" )."_".( $order == SORT_ASC ? "asc" : "desc" ).( $with_id0 ? "_with_id0" : "" ));
1194
-
1195
- foreach ($sortable_array as $k => $v) {
1196
- $new_array[$k] = $array[$k];
1197
- }
1198
- }
1199
-
1200
- return $new_array;
1201
- }
1202
-
1203
- /**
1204
- * Output Array Contents.
1205
- *
1206
- * This function echoes array contents to show properly in a front-end page.
1207
- *
1208
- * @since 3.4.0
1209
- *
1210
- * @param array $arr. The array to echo.
1211
- */
1212
- function wfu_echo_array($arr) {
1213
- if ( !is_array($arr) ) return;
1214
- echo '<pre>'.print_r($arr, true).'</pre>';
1215
- }
1216
-
1217
- /**
1218
- * Minify Code.
1219
- *
1220
- * This function minifies a piece of code. It is used to minify inline code of
1221
- * the plugin. It supports minification of Javascript or CSS code.
1222
- *
1223
- * @since 4.2.0
1224
- *
1225
- * @param string $lang. The code language. It can be 'JS' or 'CSS'.
1226
- * @param string $code. The code to minify.
1227
- *
1228
- * @return array An array holding minification result. Item 'result' is true if
1229
- * minification was successful and false otherwise. Item 'minified_code'
1230
- * holds the minified code.
1231
- */
1232
- function wfu_minify_code($lang, $code) {
1233
- $ret = array( "result" => false, "minified_code" => "" );
1234
- $php_version = preg_replace("/-.*/", "", phpversion());
1235
- $unsupported = false;
1236
- $ret = wfu_compare_versions($php_version, '5.3.0');
1237
- $unsupported = ( $ret['status'] && $ret['result'] == 'lower' );
1238
- if ( !$unsupported ) {
1239
- $path = ABSWPFILEUPLOAD_DIR;
1240
- if ( !class_exists('MatthiasMullie\Minify\Minify') ) {
1241
- include_once $path.'vendor/minifier/minify/src/Minify.php';
1242
- include_once $path.'vendor/minifier/minify/src/CSS.php';
1243
- include_once $path.'vendor/minifier/minify/src/JS.php';
1244
- include_once $path.'vendor/minifier/minify/src/Exception.php';
1245
- include_once $path.'vendor/minifier/minify/src/Exceptions/BasicException.php';
1246
- include_once $path.'vendor/minifier/minify/src/Exceptions/FileImportException.php';
1247
- include_once $path.'vendor/minifier/minify/src/Exceptions/IOException.php';
1248
- }
1249
- if ( !class_exists('MatthiasMullie\PathConverter\Converter') ) {
1250
- include_once $path.'vendor/minifier/path-converter/src/ConverterInterface.php';
1251
- include_once $path.'vendor/minifier/path-converter/src/Converter.php';
1252
- }
1253
- $minifier = null;
1254
- eval('$minifier = new MatthiasMullie\Minify\\'.strtoupper($lang).'($code);');
1255
- if ( $minifier !== null ) {
1256
- $ret["result"] = true;
1257
- $ret["minified_code"] = $minifier->minify();
1258
- }
1259
- }
1260
-
1261
- return $ret;
1262
- }
1263
-
1264
- /**
1265
- * Prepare CSS Code for Output.
1266
- *
1267
- * This function prepares CSS code for HTML output. It minifies the code if
1268
- * necessary and encloses it in <style> tags.
1269
- *
1270
- * @since 4.0.0
1271
- *
1272
- * @param string $css. The CSS code to output.
1273
- *
1274
- * @return string The resulted HTML code.
1275
- */
1276
- function wfu_css_to_HTML($css) {
1277
- if ( WFU_VAR("WFU_MINIFY_INLINE_CSS") == "true" ) {
1278
- $ret = wfu_minify_code("CSS", $css);
1279
- if ( $ret["result"] ) $css = $ret["minified_code"];
1280
- }
1281
- $echo_str = "\n\t".'<style>';
1282
- $echo_str .= "\n".$css;
1283
- $echo_str .= "\n\t".'</style>';
1284
-
1285
- return $echo_str;
1286
- }
1287
-
1288
- /**
1289
- * Prepare Javascript Code for Output.
1290
- *
1291
- * This function prepares Javascript code for HTML output. It minifies the code
1292
- * if necessary and encloses it in <script> tags.
1293
- *
1294
- * @since 4.0.0
1295
- *
1296
- * @param string $js. The Javascript code to output.
1297
- *
1298
- * @return string The resulted HTML code.
1299
- */
1300
- function wfu_js_to_HTML($js) {
1301
- if ( WFU_VAR("WFU_MINIFY_INLINE_JS") == "true" ) {
1302
- $ret = wfu_minify_code("JS", $js);
1303
- if ( $ret["result"] ) $js = $ret["minified_code"];
1304
- }
1305
- $echo_str = '<script type="text/javascript">';
1306
- $echo_str .= "\n".$js;
1307
- $echo_str .= "\n".'</script>';
1308
-
1309
- return $echo_str;
1310
- }
1311
-
1312
- /**
1313
- * Generate Basic Inline Javascript Loader Functions.
1314
- *
1315
- * This function returns the initialization code of the basic inline JS loader
1316
- * functions:
1317
- *
1318
- * wfu_js_decode_obj: This JS function generates an object from its string
1319
- * representation.
1320
- *
1321
- * wfu_run_js: This JS function calls other JS functions. It is used to run
1322
- * inline functions safely. Inline functions use objects, like GlobalData,
1323
- * which initialize after Javascript files of the plugin have been loaded.
1324
- * Usually these files are declared at the header of a page and load before
1325
- * the inline code. So objects like GlobalData have been initialized and
1326
- * inline functions can run without errors. However sometimes Javascript files
1327
- * are declared at the footer, or handled by cache plugins and load after the
1328
- * inline code. In these cases wfu_run_js will not run the inline functions
1329
- * immediately. It will put them in a JS Bank, so that they run safely after
1330
- * the Javascript files have been loaded.
1331
- *
1332
- * @since 4.2.0
1333
- *
1334
- * @return string The HTML code of the inline Javascript loader functions.
1335
- */
1336
- function wfu_init_run_js_script() {
1337
- // $script = 'if (typeof wfu_js_decode_obj == "undefined") function wfu_js_decode_obj(obj_str) { var obj = null; if (obj_str == "window") obj = window; else { var match = obj_str.match(new RegExp(\'GlobalData(\\\\.(WFU|WFUB)\\\\[(.*?)\\\\](\\\\.(.*))?)?$\')); if (match) { obj = GlobalData; if (match[3]) obj = obj[match[2]][match[3]]; if (match[5]) obj = obj[match[5]]; } } return obj; }';
1338
- $script = 'if (typeof wfu_js_decode_obj == "undefined") function wfu_js_decode_obj(obj_str) { var obj = null; if (obj_str == "window") obj = window; else { var dbs = String.fromCharCode(92); var match = obj_str.match(new RegExp(\'GlobalData(\' + dbs + \'.(WFU|WFUB)\' + dbs + \'[(.*?)\' + dbs + \'](\' + dbs + \'.(.*))?)?$\')); if (match) { obj = GlobalData; if (match[3]) obj = obj[match[2]][match[3]]; if (match[5]) obj = obj[match[5]]; } } return obj; }';
1339
- $script .= "\n".'if (typeof wfu_run_js == "undefined") function wfu_run_js(obj_str, func) { if (typeof GlobalData == "undefined") { if (typeof window.WFU_JS_BANK == "undefined") WFU_JS_BANK = []; WFU_JS_BANK.push({obj_str: obj_str, func: func}) } else { var obj = wfu_js_decode_obj(obj_str); if (obj) obj[func].call(obj); } }';
1340
- return wfu_js_to_HTML($script);
1341
- }
1342
-
1343
- /**
1344
- * Convert PHP Array to JS Object.
1345
- *
1346
- * This function converts an associative PHP array into a Javascript object.
1347
- *
1348
- * @since 4.0.0
1349
- *
1350
- * @param array $arr. The associative PHP array to convert.
1351
- *
1352
- * @return string The converted Javascript object as a string.
1353
- */
1354
- function wfu_PHP_array_to_JS_object($arr) {
1355
- $ret = "";
1356
- foreach ( $arr as $prop => $value ) {
1357
- if ( is_string($value) ) $ret .= ( $ret == "" ? "" : ", " )."$prop: \"$value\"";
1358
- elseif ( is_numeric($value) ) $ret .= ( $ret == "" ? "" : ", " )."$prop: $value";
1359
- elseif ( is_bool($value) ) $ret .= ( $ret == "" ? "" : ", " )."$prop: ".( $value ? "true" : "false" );
1360
- }
1361
- return ( $ret == "" ? "{ }" : "{ $ret }" );
1362
- }
1363
-
1364
- /**
1365
- * Convert PHP Array to URL GET Params.
1366
- *
1367
- * This function converts an associative PHP array into GET parameters to add in
1368
- * a URL.
1369
- *
1370
- * @since 4.9.0
1371
- *
1372
- * @param array $arr. The associative PHP array to convert.
1373
- *
1374
- * @return string The converted GET parameters.
1375
- */
1376
- function wfu_array_to_GET_params($arr) {
1377
- $str = "";
1378
- foreach ( $arr as $key => $var )
1379
- $str .= ( $str == "" ? "" : "&" ).$key."=".$var;
1380
-
1381
- return $str;
1382
- }
1383
-
1384
- //********************* Shortcode Attribute Functions **************************
1385
-
1386
- /**
1387
- * Insert a Category in a List of Categories.
1388
- *
1389
- * This function inserts a new category in a list of categories.
1390
- *
1391
- * @since 4.1.0
1392
- *
1393
- * @param array $categories. The list of categories.
1394
- * @param string $before_category. Insert the new category before this one.
1395
- * @param string $new_category. The new category to insert.
1396
- *
1397
- * @return array The updated list of categories.
1398
- */
1399
- function wfu_insert_category($categories, $before_category, $new_category) {
1400
- if ( $before_category == "" ) $index = count($categories);
1401
- else {
1402
- $index = array_search($before_category, array_keys($categories));
1403
- if ( $index === false ) $index = count($categories);
1404
- }
1405
-
1406
- return array_merge(array_slice($categories, 0, $index), $new_category, array_slice($categories, $index));
1407
- }
1408
-
1409
- /**
1410
- * Insert new Attributes in a List of Attributes.
1411
- *
1412
- * This function inserts one or more attributes in a list of attributes.
1413
- *
1414
- * @since 4.1.0
1415
- *
1416
- * @param array $attributes. The list of attributes.
1417
- * @param string $in_category. Insert the new attribute in this category.
1418
- * @param string $in_subcategory. Insert the new attribute in this subcategory.
1419
- * @param string $position. Position of the new attribute. It can be 'first' or
1420
- * 'last'.
1421
- * @param array $new_attributes. The new attributes to insert.
1422
- *
1423
- * @return array The updated list of attributes.
1424
- */
1425
- function wfu_insert_attributes($attributes, $in_category, $in_subcategory, $position, $new_attributes) {
1426
- $index = -1;
1427
- if ( $in_category == "" ) {
1428
- if ( $position == "first" ) $index = 0;
1429
- elseif ( $position == "last" ) $index = count($attributes);
1430
- }
1431
- else {
1432
- foreach ( $attributes as $pos => $attribute ) {
1433
- $match = ( $attribute["category"] == $in_category );
1434
- if ( $in_subcategory != "" ) $match = $match && ( $attribute["subcategory"] == $in_subcategory );
1435
- if ( $match ) {
1436
- if ( $position == "first" ) {
1437
- $index = $pos;
1438
- break;
1439
- }
1440
- elseif ( $position == "last" ) {
1441
- $index = $pos + 1;
1442
- }
1443
- }
1444
- }
1445
- }
1446
- if ( $index > -1 ) array_splice($attributes, $index, 0, $new_attributes);
1447
-
1448
- return $attributes;
1449
- }
1450
-
1451
- //********************* Plugin Options Functions *******************************
1452
-
1453
- /**
1454
- * Get Server Environment.
1455
- *
1456
- * This function gets the server environment, whether it is 32 or 64 bit.
1457
- *
1458
- * @since 2.6.0
1459
- *
1460
- * @redeclarable
1461
- *
1462
- * @return string The server environment, '32bit' or '64bit'.
1463
- */
1464
- function wfu_get_server_environment() {
1465
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
1466
- $php_env = '';
1467
- if ( PHP_INT_SIZE == 4 ) $php_env = '32bit';
1468
- elseif ( PHP_INT_SIZE == 8 ) $php_env = '64bit';
1469
- else {
1470
- $int = "9223372036854775807";
1471
- $int = intval($int);
1472
- if ($int == 9223372036854775807) $php_env = '64bit';
1473
- elseif ($int == 2147483647) $php_env = '32bit';
1474
- }
1475
-
1476
- return $php_env;
1477
- }
1478
-
1479
- /**
1480
- * Get AJAX URL.
1481
- *
1482
- * This function gets the URL of admin-ajax.php for AJAX requests.
1483
- *
1484
- * @since 3.7.2
1485
- *
1486
- * @redeclarable
1487
- *
1488
- * @return string The full URL for AJAX requests.
1489
- */
1490
- function wfu_ajaxurl() {
1491
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
1492
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
1493
- return ( $plugin_options['admindomain'] == 'siteurl' || $plugin_options['admindomain'] == '' ? site_url("wp-admin/admin-ajax.php") : ( $plugin_options['admindomain'] == 'adminurl' ? admin_url("admin-ajax.php") : home_url("wp-admin/admin-ajax.php") ) );
1494
- }
1495
-
1496
- /**
1497
- * Get Plugin Environment Variable Value.
1498
- *
1499
- * This function gets the value of a plugin's environment variable.
1500
- *
1501
- * @since 3.7.1
1502
- *
1503
- * @param string $varname The name of the environment variable.
1504
- *
1505
- * @return mixed The value of the environment variable.
1506
- */
1507
- function WFU_VAR($varname) {
1508
- if ( !isset($GLOBALS["WFU_GLOBALS"][$varname]) ) return false;
1509
- if ( $GLOBALS["WFU_GLOBALS"][$varname][5] ) return $GLOBALS["WFU_GLOBALS"][$varname][3];
1510
- //in case the environment variable is hidden then return the default value
1511
- else return $GLOBALS["WFU_GLOBALS"][$varname][2];
1512
- }
1513
-
1514
- /**
1515
- * Get Plugin Version.
1516
- *
1517
- * This function gets the plugin's version.
1518
- *
1519
- * @since 2.4.6
1520
- *
1521
- * @return string The plugin's version.
1522
- */
1523
- function wfu_get_plugin_version() {
1524
- $plugin_data = get_plugin_data(WPFILEUPLOAD_PLUGINFILE);
1525
- return $plugin_data['Version'];
1526
- }
1527
-
1528
- /**
1529
- * Get Plugin's Latest Version.
1530
- *
1531
- * This function gets the plugin's latest version from Iptanus Services Server.
1532
- *
1533
- * @since 2.4.6
1534
- *
1535
- * @redeclarable
1536
- *
1537
- * @return string The plugin's latest version.
1538
- */
1539
- function wfu_get_latest_version() {
1540
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
1541
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
1542
- $postfields = array();
1543
- $postfields['action'] = 'wfuca_check_latest_version_free';
1544
- $postfields['version_hash'] = WFU_VERSION_HASH;
1545
- $url = ( $plugin_options["altserver"] == "1" && trim(WFU_VAR("WFU_ALT_IPTANUS_SERVER")) != "" ? ( trim(WFU_VAR("WFU_ALT_VERSION_SERVER")) != "" ? trim(WFU_VAR("WFU_ALT_VERSION_SERVER")) : trim(WFU_VAR("WFU_ALT_IPTANUS_SERVER")).'/wp-admin/admin-ajax.php' ) : WFU_VERSION_SERVER_URL );
1546
- $result = null;
1547
- if ( WFU_VAR("WFU_DISABLE_VERSION_CHECK") != "true" )
1548
- $result = wfu_post_request($url, $postfields, false, false, 10);
1549
- return $result;
1550
- }
1551
-
1552
- /**
1553
- * Compare Current and Latest Version.
1554
- *
1555
- * This function compares curent version with latest one.
1556
- *
1557
- * @since 2.4.6
1558
- *
1559
- * @param string $current The curent plugin version.
1560
- * @param string $latest The latest plugin version.
1561
- *
1562
- * @return string The comparison result. It can have the following values:
1563
- * 'equal': both versions are equal.
1564
- * 'lower': current version is lower than latest.
1565
- * 'current version invalid' current version is invalid.
1566
- * 'latest version invalid' latest version is invalid.
1567
- */
1568
- function wfu_compare_versions($current, $latest) {
1569
- $ret['status'] = true;
1570
- $ret['custom'] = false;
1571
- $ret['result'] = 'equal';
1572
- $res = preg_match('/^([0-9]*)\.([0-9]*)\.([0-9]*)(.*)/', $current, $cur_data);
1573
- if ( !$res || count($cur_data) < 5 )
1574
- return array( 'status' => false, 'custom' => false, 'result' => 'current version invalid' );
1575
- if ( $cur_data[1] == '' || $cur_data[2] == '' || $cur_data[3] == '' )
1576
- return array( 'status' => false, 'custom' => false, 'result' => 'current version invalid' );
1577
- $custom = ( $cur_data[4] != '' );
1578
- $res = preg_match('/^([0-9]*)\.([0-9]*)\.([0-9]*)/', $latest, $lat_data);
1579
- if ( !$res || count($lat_data) < 4 )
1580
- return array( 'status' => false, 'custom' => $custom, 'result' => 'latest version invalid' );
1581
- if ( $lat_data[1] == '' || $lat_data[2] == '' || $lat_data[3] == '' )
1582
- return array( 'status' => false, 'custom' => $custom, 'result' => 'latest version invalid' );
1583
- if ( intval($cur_data[1]) < intval($lat_data[1]) )
1584
- return array( 'status' => true, 'custom' => $custom, 'result' => 'lower' );
1585
- elseif ( intval($cur_data[1]) > intval($lat_data[1]) )
1586
- return array( 'status' => false, 'custom' => $custom, 'result' => 'current version invalid' );
1587
- if ( intval($cur_data[2]) < intval($lat_data[2]) )
1588
- return array( 'status' => true, 'custom' => $custom, 'result' => 'lower' );
1589
- elseif ( intval($cur_data[2]) > intval($lat_data[2]) )
1590
- return array( 'status' => false, 'custom' => $custom, 'result' => 'current version invalid' );
1591
- if ( intval($cur_data[3]) < intval($lat_data[3]) )
1592
- return array( 'status' => true, 'custom' => $custom, 'result' => 'lower' );
1593
- elseif ( intval($cur_data[3]) > intval($lat_data[3]) )
1594
- return array( 'status' => false, 'custom' => $custom, 'result' => 'current version invalid' );
1595
- return array( 'status' => true, 'custom' => $custom, 'result' => 'equal' );
1596
- }
1597
-
1598
- //********************* File / Directory Functions *****************************
1599
-
1600
- /**
1601
- * Get Root Path of Website.
1602
- *
1603
- * This function gets the root (absolute) path of the website. If it cannot be
1604
- * retrieved then content path is returned.
1605
- *
1606
- * @since 4.0.0
1607
- *
1608
- * @return string The absolute path of the website.
1609
- */
1610
- function wfu_abspath() {
1611
- $path = WP_CONTENT_DIR;
1612
- //remove trailing slash if exists
1613
- if ( substr($path, -1) == '/' ) $path = substr($path, 0, -1);
1614
- $pos = strrpos($path, '/');
1615
- //to find abspath we go one dir up from content path
1616
- if ( $pos !== false ) $path = substr($path, 0, $pos + 1);
1617
- //else if we cannot go up we stay at content path adding a trailing slash
1618
- else $path .= '/';
1619
-
1620
- return $path;
1621
- }
1622
-
1623
- /**
1624
- * Extract Extension from Filename.
1625
- *
1626
- * This function extracts the extension part from filename.
1627
- *
1628
- * @since 3.8.0
1629
- *
1630
- * @param string $basename The filename to extract the extension from.
1631
- * @param bool $with_dot Optional. If true the dot symbol will be included in
1632
- * the extension.
1633
- *
1634
- * @return string The extracted extension.
1635
- */
1636
- function wfu_fileext($basename, $with_dot = false) {
1637
- if ( $with_dot ) return preg_replace("/^.*?(\.[^.]*)?$/", "$1", $basename);
1638
- else return preg_replace("/^.*?(\.([^.]*))?$/", "$2", $basename);
1639
- }
1640
-
1641
- /**
1642
- * Extract Name Part from Filename.
1643
- *
1644
- * This function extracts the name part from filename without the extension.
1645
- *
1646
- * @since 3.8.0
1647
- *
1648
- * @param string $basename The filename to extract the name part from.
1649
- *
1650
- * @return string The extracted name part.
1651
- */
1652
- function wfu_filename($basename) {
1653
- return preg_replace("/^(.*?)(\.[^.]*)?$/", "$1", $basename);
1654
- }
1655
-
1656
- /**
1657
- * Extract Filename From Path.
1658
- *
1659
- * This function extracts the filename from path.
1660
- *
1661
- * @since 2.6.0
1662
- *
1663
- * @param string $path The path to extract the filename from.
1664
- *
1665
- * @return string The extracted filename.
1666
- */
1667
- function wfu_basename($path) {
1668
- if ( !$path || $path == "" ) return "";
1669
- return preg_replace('/.*(\\\\|\\/)/', '', $path);
1670
- }
1671
-
1672
- /**
1673
- * Extract Dir From Path.
1674
- *
1675
- * This function extracts the dir part from path without the filename.
1676
- *
1677
- * @since 2.7.1
1678
- *
1679
- * @param string $path The path to extract the dir part from.
1680
- *
1681
- * @return string The extracted dir part.
1682
- */
1683
- function wfu_basedir($path) {
1684
- if ( !$path || $path == "" ) return "";
1685
- return substr($path, 0, strlen($path) - strlen(wfu_basename($path)));
1686
- }
1687
-
1688
- /**
1689
- * Convert Absolute Path to Relative.
1690
- *
1691
- * This function converts an absolute path to relative one by removing the
1692
- * root path of the website. If the path points to an FTP location then no
1693
- * conversion happens. If the path is outside the root, then 'abs:' is appended
1694
- * to the path.
1695
- *
1696
- * @since 3.1.0
1697
- *
1698
- * @param string $path The absolute path.
1699
- *
1700
- * @return string The relative path.
1701
- */
1702
- function wfu_path_abs2rel($path) {
1703
- $abspath_notrailing_slash = substr(wfu_abspath(), 0, -1);
1704
- if ( substr($path, 0, 6) == 'ftp://' || substr($path, 0, 7) == 'ftps://' || substr($path, 0, 7) == 'sftp://' ) return $path;
1705
- else {
1706
- $is_outside_root = ( substr($path, 0, strlen($abspath_notrailing_slash)) != $abspath_notrailing_slash );
1707
- if ( $is_outside_root ) return 'abs:'.$path;
1708
- // else return str_replace($abspath_notrailing_slash, "", $path);
1709
- else return substr($path, strlen($abspath_notrailing_slash));
1710
- }
1711
- }
1712
-
1713
- /**
1714
- * Convert Relative Path to Absolute.
1715
- *
1716
- * This function converts a relative path to absolute one by prepending the root
1717
- * path of the website.
1718
- *
1719
- * @since 3.1.0
1720
- *
1721
- * @param string $path The relative path.
1722
- *
1723
- * @return string The absolute path.
1724
- */
1725
- function wfu_path_rel2abs($path) {
1726
- if ( substr($path, 0, 1) == "/" ) $path = substr($path, 1);
1727
- if ( substr($path, 0, 6) == 'ftp://' || substr($path, 0, 7) == 'ftps://' || substr($path, 0, 7) == 'sftp://' ) return $path;
1728
- elseif ( substr($path, 0, 4) == 'abs:' ) return substr($path, 4);
1729
- else return wfu_abspath().$path;
1730
- }
1731
-
1732
- /**
1733
- * Delete an Uploaded File.
1734
- *
1735
- * This function deletes an uploaded file from the website. It marks the file as
1736
- * deleted in the database. It also deletes any linked attachments or
1737
- * thumbnails.
1738
- *
1739
- * @since 4.2.0
1740
- *
1741
- * @redeclarable
1742
- *
1743
- * @param string $filepath The path of the file to delete.
1744
- * @param int $userid The ID of the user who performs the deletion.
1745
- * @param object $filerec Optional. The db record of the file, if available.
1746
- *
1747
- * @return bool True if the deletion succeeded, false otherwise.
1748
- */
1749
- function wfu_delete_file_execute($filepath, $userid, $filerec = null) {
1750
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
1751
- if ( $filerec == null ) $filedata = wfu_get_filedata($filepath);
1752
- else $filedata = wfu_get_filedata_from_rec($filerec, true, false, false);
1753
- $delete_rec = true;
1754
- if ( $delete_rec ) $retid = wfu_log_action('delete', $filepath, $userid, '', 0, 0, '', null, $filerec);
1755
- $result = wfu_unlink($filepath, "wfu_delete_file_execute");
1756
- if ( !$result ) wfu_revert_log_action($retid);
1757
- elseif ( $delete_rec ) {
1758
- //delete linked attachment if exists and it is allowed to be deleted
1759
- if ( $filedata != null && isset($filedata["media"]) && WFU_VAR("WFU_UPDATE_MEDIA_ON_DELETE") == "true" )
1760
- wp_delete_attachment( $filedata["media"]["attach_id"] );
1761
- }
1762
-
1763
- return $result;
1764
- }
1765
-
1766
- /**
1767
- * Extract FTP Information From ftpinfo Attribute.
1768
- *
1769
- * This function extracts FTP information from ftpinfo attribute of the uploader
1770
- * shortcode.
1771
- *
1772
- * @since 4.11.2
1773
- *
1774
- * @param string $ftpdata The ftpinfo attribute.
1775
- *
1776
- * @return array {
1777
- * An array of extracted FTP information.
1778
- *
1779
- * @type bool $error Defines whether there was an error during
1780
- * extraction of FTP information.
1781
- * @type array $data {
1782
- * The extracted FTP information.
1783
- *
1784
- * @type string $username The FTP login username.
1785
- * @type string $password The FTP login password.
1786
- * @type string $ftpdomain The FTP domain.
1787
- * @type string $port The FTP port.
1788
- * @type bool $sftp Defines whether sFTP connection will be used.
1789
- * }
1790
- * }
1791
- */
1792
- function wfu_decode_ftpinfo($ftpdata) {
1793
- $ret = array(
1794
- "error" => true,
1795
- "data" => array(
1796
- "username" => "",
1797
- "password" => "",
1798
- "ftpdomain" => "",
1799
- "port" => "",
1800
- "sftp" => false
1801
- )
1802
- );
1803
- $ftpdata_flat = str_replace(array('\\:', '\\@'), array('\\_', '\\_'), $ftpdata);
1804
- $pos1 = strpos($ftpdata_flat, ":");
1805
- $pos2 = strpos($ftpdata_flat, "@");
1806
- if ( $pos1 && $pos2 && $pos2 > $pos1 ) {
1807
- $ret["error"] = false;
1808
- $ret["data"]["username"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), substr($ftpdata, 0, $pos1));
1809
- $ret["data"]["password"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), substr($ftpdata, $pos1 + 1, $pos2 - $pos1 - 1));
1810
- $ftp_host = substr($ftpdata, $pos2 + 1);
1811
- $ret["data"]["ftpdomain"] = preg_replace("/:.*/", "", $ftp_host);
1812
- if ( trim($ret["data"]["ftpdomain"]) == "" ) $ret["error"] = true;
1813
- $ftp_port = preg_replace("/^[^:]*:?/", "", $ftp_host);
1814
- if ( substr($ftp_port, 0, 1) == "s" ) {
1815
- $ret["data"]["sftp"] = true;
1816
- $ftp_port = substr($ftp_port, 1);
1817
- }
1818
- $ret["data"]["port"] = $ftp_port;
1819
- }
1820
- elseif ( $pos2 ) {
1821
- $ret["error"] = false;
1822
- $ret["data"]["username"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), substr($ftpdata, 0, $pos2));
1823
- $ftp_host = substr($ftpdata, $pos2 + 1);
1824
- $ret["data"]["ftpdomain"] = preg_replace("/:.*/", "", $ftp_host);
1825
- if ( trim($ret["data"]["ftpdomain"]) == "" ) $ret["error"] = true;
1826
- $ftp_port = preg_replace("/^[^:]*:?/", "", $ftp_host);
1827
- if ( substr($ftp_port, 0, 1) == "s" ) {
1828
- $ret["data"]["sftp"] = true;
1829
- $ftp_port = substr($ftp_port, 1);
1830
- }
1831
- $ret["data"]["port"] = $ftp_port;
1832
- }
1833
- elseif ( $pos1 ) {
1834
- $ret["error"] = true;
1835
- $ret["data"]["username"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), substr($ftpdata, 0, $pos1));
1836
- $ret["data"]["password"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'),substr($ftpdata, $pos1 + 1));
1837
- }
1838
- else {
1839
- $ret["error"] = true;
1840
- $ret["data"]["username"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), $ftpdata);
1841
- }
1842
-
1843
- return $ret;
1844
- }
1845
-
1846
- /**
1847
- * Extract FTP Information From FTP URL.
1848
- *
1849
- * This function extracts FTP information from an FTP URL.
1850
- *
1851
- * @since 4.15.0
1852
- *
1853
- * @param string $url The FTP URL.
1854
- *
1855
- * @return array {
1856
- * An array of extracted FTP information.
1857
- *
1858
- * @type bool $error Defines whether there was an error during
1859
- * extraction of FTP information.
1860
- * @type array $data {
1861
- * The extracted FTP information.
1862
- *
1863
- * @type string $username The FTP login username.
1864
- * @type string $password The FTP login password.
1865
- * @type string $ftpdomain The FTP domain.
1866
- * @type string $port The FTP port.
1867
- * @type bool $sftp Defines whether sFTP connection will be used.
1868
- * @type string $filepath The local path to the file.
1869
- * }
1870
- * }
1871
- */
1872
- function wfu_decode_ftpurl($url) {
1873
- $ftpinfo = array(
1874
- "error" => true,
1875
- "data" => array(
1876
- "username" => "",
1877
- "password" => "",
1878
- "ftpdomain" => "",
1879
- "port" => "",
1880
- "sftp" => false,
1881
- "filepath" => ""
1882
- )
1883
- );
1884
- if ( substr($url, 0, 6) != "ftp://" && substr($url, 0, 7) != "sftp://" ) return $ftpinfo;
1885
- $issftp = ( substr($url, 0, 7) == "sftp://" );
1886
- $filepath = ( $issftp ? substr($url, 7) : substr($url, 6) );
1887
- $pos = strpos($filepath, '/');
1888
- if ( $pos === false ) return $ftpinfo;
1889
- //separate sftp info
1890
- $ftpdata = substr($filepath, 0, $pos);
1891
- $filepath = substr($filepath, $pos);
1892
- $ftpinfo = wfu_decode_ftpinfo($ftpdata);
1893
- if ( $ftpinfo["error"] ) return $ftpinfo;
1894
- $data = $ftpinfo["data"];
1895
- //decode encoded characters in username and password
1896
- $data["username"] = str_replace(array('%40', '%3A', '%2F'), array('@', ':', '/'), $data["username"]);
1897
- $data["password"] = str_replace(array('%40', '%3A', '%2F'), array('@', ':', '/'), $data["password"]);
1898
- $data["sftp"] = $issftp;
1899
- if ( $data["port"] == "" ) $data["port"] = ( $issftp ? "22" : "80" );
1900
- $data["filepath"] = $filepath;
1901
- $ftpinfo["data"] = $data;
1902
- return $ftpinfo;
1903
- }
1904
-
1905
- /**
1906
- * Hide Credentials From FTP URL.
1907
- *
1908
- * This function hides strips username and password information from an FTP URL.
1909
- *
1910
- * @since 4.15.0
1911
- *
1912
- * @param string $url The file URL.
1913
- *
1914
- * @return string The stripped URL.
1915
- */
1916
- function wfu_hide_credentials_from_ftpurl($url) {
1917
- return preg_replace("/^(ftp|sftp)(:\/\/)([^@]*@)(.*$)/", "$1$2$4", $url);
1918
- }
1919
-
1920
- /**
1921
- * Get Full Upload Path.
1922
- *
1923
- * This function calculates the full upload path of an uploader shortcode from
1924
- * its attributes.
1925
- *
1926
- * @since 2.1.2
1927
- *
1928
- * @param array $params The shortcode attributes.
1929
- *
1930
- * @return string The full uplod path.
1931
- */
1932
- function wfu_upload_plugin_full_path( $params ) {
1933
- $path = $params["uploadpath"];
1934
- if ( $params["accessmethod"] == 'ftp' && $params["ftpinfo"] != '' && $params["useftpdomain"] == "true" ) {
1935
- //remove parent folder symbol (..) in path so that the path does not go outside host
1936
- $ftpdata = str_replace('..', '', $params["ftpinfo"]);
1937
- $ftpinfo = wfu_decode_ftpinfo($ftpdata);
1938
- if ( !$ftpinfo["error"] ) {
1939
- $data = $ftpinfo["data"];
1940
- //extract relative FTP path
1941
- $ftp_port = $data["port"];
1942
- if ( $data["sftp"] && $ftp_port == "" ) $ftp_port = "22";
1943
- $ftp_host = $data["ftpdomain"].( $ftp_port != "" ? ":".$ftp_port : "" );
1944
- $ftp_username = str_replace(array('@', ':', '/'), array('%40', '%3A', '%2F'), $data["username"]); //if username contains @, :, / characters then encode them
1945
- $ftp_password = str_replace(array('@', ':', '/'), array('%40', '%3A', '%2F'), $data["password"]); //if username contains @, :, / characters then encode them
1946
- $start_folder = ( $data["sftp"] ? 's' : '' ).'ftp://'.$ftp_username.':'.$ftp_password."@".$ftp_host.'/';
1947
- }
1948
- else $start_folder = 'ftp://'.$params["ftpinfo"].'/';
1949
- }
1950
- else $start_folder = WP_CONTENT_DIR.'/';
1951
- if ($path) {
1952
- if ( $path == ".." || substr($path, 0, 3) == "../" ) {
1953
- $start_folder = wfu_abspath();
1954
- $path = substr($path, 2, strlen($path) - 2);
1955
- }
1956
- //remove additional parent folder symbols (..) in path so that the path does not go outside the $start_folder
1957
- $path = str_replace('..', '', $path);
1958
- if ( substr($path, 0, 1) == "/" ) $path = substr($path, 1, strlen($path) - 1);
1959
- if ( substr($path, -1, 1) == "/" ) $path = substr($path, 0, strlen($path) - 1);
1960
- $full_upload_path = $start_folder;
1961
- if ( $path != "" ) $full_upload_path .= $path.'/';
1962
- }
1963
- else {
1964
- $full_upload_path = $start_folder;
1965
- }
1966
- return $full_upload_path;
1967
- }
1968
-
1969
- /**
1970
- * Get Full Upload Path.
1971
- *
1972
- * This function calculates the full upload path of an uploader shortcode from
1973
- * its attributes.
1974
- *
1975
- * @since 2.1.2
1976
- *
1977
- * @param array $params The shortcode attributes.
1978
- *
1979
- * @return string The full upload path.
1980
- */
1981
- function wfu_upload_plugin_directory( $path ) {
1982
- $dirparts = explode("/", $path);
1983
- return $dirparts[count($dirparts) - 1];
1984
- }
1985
-
1986
- /**
1987
- * Extract Additional Data From Complex Path.
1988
- *
1989
- * This function is used to extract sort, filename or filter information from
1990
- * a complex path. A complex path is used by the plugin to pass additional
1991
- * information between requests. In a complex path sort, filename and filter
1992
- * information are stored as [[-sort]], {{filename}} and ((filter)).
1993
- *
1994
- * @since 2.2.1
1995
- *
1996
- * @param string $path The complex path.
1997
- *
1998
- * @return array {
1999
- * Additional data extracted from path.
2000
- *
2001
- * @type string $path The clean path.
2002
- * @type string $sort Sort information of a file list.
2003
- * @type string $file Filename of a specific file.
2004
- * @type string $filter Filter information of a file list.
2005
- * }
2006
- */
2007
- function wfu_extract_sortdata_from_path($path) {
2008
- $ret['path'] = $path;
2009
- $ret['sort'] = "";
2010
- $ret['file'] = "";
2011
- $ret['filter'] = "";
2012
- //extract sort info
2013
- $pos1 = strpos($path, '[[');
2014
- $pos2 = strpos($path, ']]');
2015
- if ( $pos1 !== false && $pos2 !== false )
2016
- if ( $pos2 > $pos1 ) {
2017
- $ret['sort'] = substr($path, $pos1 + 2, $pos2 - $pos1 - 2);
2018
- $ret['path'] = str_replace('[['.$ret['sort'].']]', '', $path);
2019
- }
2020
- //extract filename info
2021
- $pos1 = strpos($path, '{{');
2022
- $pos2 = strpos($path, '}}');
2023
- if ( $pos1 !== false && $pos2 !== false )
2024
- if ( $pos2 > $pos1 ) {
2025
- $ret['file'] = substr($path, $pos1 + 2, $pos2 - $pos1 - 2);
2026
- $ret['path'] = str_replace('{{'.$ret['file'].'}}', '', $path);
2027
- }
2028
- //extract filter info
2029
- $pos1 = strpos($path, '((');
2030
- $pos2 = strpos($path, '))');
2031
- if ( $pos1 !== false && $pos2 !== false )
2032
- if ( $pos2 > $pos1 ) {
2033
- $ret['filter'] = substr($path, $pos1 + 2, $pos2 - $pos1 - 2);
2034
- $ret['path'] = str_replace('(('.$ret['filter'].'))', '', $path);
2035
- }
2036
- return $ret;
2037
- }
2038
-
2039
- /**
2040
- * Flatten A Complex Path.
2041
- *
2042
- * This function returns only the clean path from a complex path.
2043
- *
2044
- * @since 2.2.1
2045
- *
2046
- * @param string $path The complex path.
2047
- *
2048
- * @return string The clean path.
2049
- */
2050
- function wfu_flatten_path($path) {
2051
- $ret = wfu_extract_sortdata_from_path($path);
2052
- return $ret['path'];
2053
- }
2054
-
2055
- /**
2056
- * Delete a Directory Recursively.
2057
- *
2058
- * This function deletes a directory recursively.
2059
- *
2060
- * @since 2.2.1
2061
- *
2062
- * @param string $dir The directory to delete.
2063
- *
2064
- * @return bool True if the deletion suceeded, false otherwise.
2065
- */
2066
- function wfu_delTree($dir) {
2067
- $files = array_diff(scandir($dir), array('.','..'));
2068
- foreach ($files as $file) {
2069
- is_dir("$dir/$file") ? wfu_delTree("$dir/$file") : unlink("$dir/$file");
2070
- }
2071
- return rmdir($dir);
2072
- }
2073
-
2074
- /**
2075
- * Get Top-Level Subdirectory Tree of a Directory.
2076
- *
2077
- * This function retrieves the first-level subdirectories of a directory.
2078
- *
2079
- * @since 2.7.1
2080
- *
2081
- * @param string $dir The directory to scan.
2082
- *
2083
- * @return array An array of subdirectories.
2084
- */
2085
- function wfu_getTree($dir) {
2086
- $tree = array();
2087
- $files = @scandir($dir);
2088
- if ( !is_array($files) ) $files = array();
2089
- $files = array_diff($files, array('.','..'));
2090
- foreach ($files as $file) {
2091
- if ( is_dir("$dir/$file") ) array_push($tree, $file);
2092
- }
2093
- return $tree;
2094
- }
2095
- /**
2096
- * Parse List of Folders From subfoldertree Attribute.
2097
- *
2098
- * This function calculates the list of subfolders of a subfoldertree attribute
2099
- * of an uploader shortcode.
2100
- *
2101
- * @since 2.4.1
2102
- *
2103
- * @redeclarable
2104
- *
2105
- * @param string $subfoldertree The subfoldertree attribute of the shortcode.
2106
- *
2107
- * @return array {
2108
- * An array of folders.
2109
- *
2110
- * @type array $path An array of folder paths.
2111
- * @type array $label An array of folder labels.
2112
- * @type array $level An array of folder levels.
2113
- * @type array $default An array defining which item is default.
2114
- * }
2115
- */
2116
- function wfu_parse_folderlist($subfoldertree) {
2117
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2118
- $ret['path'] = array();
2119
- $ret['label'] = array();
2120
- $ret['level'] = array();
2121
- $ret['default'] = array();
2122
-
2123
- if ( substr($subfoldertree, 0, 4) == "auto" ) return $ret;
2124
- $subfolders = explode(",", $subfoldertree);
2125
- if ( count($subfolders) == 0 ) return $ret;
2126
- if ( count($subfolders) == 1 && trim($subfolders[0]) == "" ) return $ret;
2127
- $dir_levels = array ( "root" );
2128
- $prev_level = 0;
2129
- $level0_count = 0;
2130
- $default = -1;
2131
- foreach ($subfolders as $subfolder) {
2132
- $subfolder = trim($subfolder);
2133
- $star_count = 0;
2134
- $start_spaces = "";
2135
- $is_default = false;
2136
- //check for folder level
2137
- while ( $star_count < strlen($subfolder) ) {
2138
- if ( substr($subfolder, $star_count, 1) == "*" ) {
2139
- $star_count ++;
2140
- $start_spaces .= "&nbsp;&nbsp;&nbsp;";
2141
- }
2142
- else break;
2143
- }
2144
- if ( $star_count - $prev_level <= 1 && ( $star_count > 0 || $level0_count == 0 ) ) {
2145
- $subfolder = substr($subfolder, $star_count, strlen($subfolder) - $star_count);
2146
- // check for default value
2147
- if ( substr($subfolder, 0, 1) == '&' ) {
2148
- $subfolder = substr($subfolder, 1);
2149
- $is_default = true;
2150
- }
2151
- //split item in folder path and folder name
2152
- $subfolder_items = explode('/', $subfolder);
2153
- if ( count($subfolder_items) > 1 && $subfolder_items[1] != "" ) {
2154
- $subfolder_dir = $subfolder_items[0];
2155
- $subfolder_label = $subfolder_items[1];
2156
- }
2157
- else {
2158
- $subfolder_dir = $subfolder;
2159
- $subfolder_label = $subfolder;
2160
- }
2161
- if ( $subfolder_dir != "" ) {
2162
- // set is_default flag to true only for the first default item
2163
- if ( $is_default && $default == -1 ) $default = count($ret['path']);
2164
- else $is_default = false;
2165
- // set flag that root folder has been included (so that it is not included it again)
2166
- if ( $star_count == 0 ) $level0_count = 1;
2167
- if ( count($dir_levels) > $star_count ) $dir_levels[$star_count] = $subfolder_dir;
2168
- else array_push($dir_levels, $subfolder_dir);
2169
- $subfolder_path = "";
2170
- for ( $i_count = 1; $i_count <= $star_count; $i_count++) {
2171
- $subfolder_path .= $dir_levels[$i_count].'/';
2172
- }
2173
- array_push($ret['path'], $subfolder_path);
2174
- array_push($ret['label'], $subfolder_label);
2175
- array_push($ret['level'], $star_count);
2176
- array_push($ret['default'], $is_default);
2177
- $prev_level = $star_count;
2178
- }
2179
- }
2180
- }
2181
-
2182
- return $ret;
2183
- }
2184
-
2185
- /**
2186
- * Calculate Size of Big File.
2187
- *
2188
- * This function calculates the size of a file. It uses a complex approach for
2189
- * calculating very big files (over 2GB) even in 32bit server environments.
2190
- *
2191
- * @since 2.6.0
2192
- *
2193
- * @param string $filepath The file path.
2194
- *
2195
- * @return The file size.
2196
- */
2197
- function wfu_bigfilesize($filepath) {
2198
- $fp = fopen($filepath, 'r');
2199
- $pos = 0;
2200
- if ($fp) {
2201
- $size = 1073741824;
2202
- fseek($fp, 0, SEEK_SET);
2203
- while ($size > 1) {
2204
- fseek($fp, $size, SEEK_CUR);
2205
- if (fgetc($fp) === false) {
2206
- fseek($fp, -$size, SEEK_CUR);
2207
- $size = (int)($size / 2);
2208
- }
2209
- else {
2210
- fseek($fp, -1, SEEK_CUR);
2211
- $pos += $size;
2212
- }
2213
- }
2214
- while (fgetc($fp) !== false) $pos++;
2215
- fclose($fp);
2216
- }
2217
-
2218
- return $pos;
2219
- }
2220
-
2221
- /**
2222
- * Alternative Calculate Size of Big File.
2223
- *
2224
- * This function calculates the size of a file following an alternative method.
2225
- * Again, it uses a complex approach for calculating very big files (over 2GB)
2226
- * even in 32bit server environments.
2227
- *
2228
- * @since 2.6.0
2229
- *
2230
- * @param string $filepath The file path.
2231
- *
2232
- * @return The file size.
2233
- */
2234
- function wfu_bigfilesize2($filepath) {
2235
- $fp = fopen($filepath, 'r');
2236
- $return = false;
2237
- if (is_resource($fp)) {
2238
- if (PHP_INT_SIZE < 8) {
2239
- // 32bit
2240
- if (0 === fseek($fp, 0, SEEK_END)) {
2241
- $return = 0.0;
2242
- $step = 0x7FFFFFFF;
2243
- while ($step > 0) {
2244
- if (0 === fseek($fp, - $step, SEEK_CUR)) {
2245
- $return += floatval($step);
2246
- } else {
2247
- $step >>= 1;
2248
- }
2249
- }
2250
- }
2251
- } elseif (0 === fseek($fp, 0, SEEK_END)) {
2252
- // 64bit
2253
- $return = ftell($fp);
2254
- }
2255
- fclose($fp);
2256
- }
2257
- return $return;
2258
- }
2259
-
2260
- /**
2261
- * Set Read Position on File.
2262
- *
2263
- * This function sets read position on a file. It uses a complex approach for
2264
- * allowing correct positioning of very big files (over 2GB) even in 32bit
2265
- * server environments.
2266
- *
2267
- * @since 2.6.0
2268
- *
2269
- * @param string $fp The file handle of the file.
2270
- * @param int $pos The read position to set.
2271
- * @param int $first Optional. If non-zero then position will start from
2272
- * beginning of file.
2273
- */
2274
- function wfu_fseek($fp, $pos, $first = 1) {
2275
- // set to 0 pos initially, one-time
2276
- if ( $first ) fseek($fp, 0, SEEK_SET);
2277
-
2278
- // get pos float value
2279
- $pos = floatval($pos);
2280
-
2281
- // within limits, use normal fseek
2282
- if ( $pos <= PHP_INT_MAX )
2283
- fseek($fp, $pos, SEEK_CUR);
2284
- // out of limits, use recursive fseek
2285
- else {
2286
- fseek($fp, PHP_INT_MAX, SEEK_CUR);
2287
- $pos -= PHP_INT_MAX;
2288
- wfu_fseek($fp, $pos, 0);
2289
- }
2290
- }
2291
-
2292
- /**
2293
- * Alternative Set Read Position on File.
2294
- *
2295
- * This function sets read position on a file following an alternative method.
2296
- * Again, tt uses a complex approach for allowing correct positioning of very
2297
- * big files (over 2GB) even in 32bit server environments.
2298
- *
2299
- * @since 2.6.0
2300
- *
2301
- * @param string $fp The file handle of the file.
2302
- * @param int $pos The read position to set.
2303
- *
2304
- * @return int Upon success, returns 0 otherwise returns -1.
2305
- */
2306
- function wfu_fseek2($fp, $pos) {
2307
- $pos = floatval($pos);
2308
- if ( $pos <= PHP_INT_MAX ) {
2309
- return fseek($fp, $pos, SEEK_SET);
2310
- }
2311
- else {
2312
- $fsize = wfu_bigfilesize2($filepath);
2313
- $opp = $fsize - $pos;
2314
- if ( 0 === ($ans = fseek($fp, 0, SEEK_END)) ) {
2315
- $maxstep = 0x7FFFFFFF;
2316
- $step = $opp;
2317
- if ( $step > $maxstep ) $step = $maxstep;
2318
- while ($step > 0) {
2319
- if ( 0 === ($ans = fseek($fp, - $step, SEEK_CUR)) ) {
2320
- $opp -= floatval($step);
2321
- }
2322
- else {
2323
- $maxstep >>= 1;
2324
- }
2325
- $step = $opp;
2326
- if ( $step > $maxstep ) $step = $maxstep;
2327
- }
2328
- }
2329
- }
2330
- return $ans;
2331
- }
2332
-
2333
- /**
2334
- * Write Message to Debug Log.
2335
- *
2336
- * This function appends a message to the plugin's debug log file. This file is
2337
- * located at /wp-content/debug_log.txt.
2338
- *
2339
- * @since 2.5.5
2340
- *
2341
- * @param string $message The message to log.
2342
- */
2343
- function wfu_debug_log($message) {
2344
- $logpath = WP_CONTENT_DIR.'/debug_log.txt';
2345
- file_put_contents($logpath, $message, FILE_APPEND);
2346
- }
2347
-
2348
- /**
2349
- * Write Object Contents to Debug Log.
2350
- *
2351
- * This function appends the contents of an object to the plugin's debug log
2352
- * file.
2353
- *
2354
- * @since 4.10.0
2355
- *
2356
- * @param mixed $obj The object to log.
2357
- */
2358
- function wfu_debug_log_obj($obj) {
2359
- wfu_debug_log(print_r($obj, true));
2360
- }
2361
-
2362
- /**
2363
- * Store Filepath to Safe.
2364
- *
2365
- * This function stores a file path into the current user's User Space and
2366
- * returns a unique code corresponding to the file path. This process is used to
2367
- * protect file paths from being exposed when needing to pass them as HTTP
2368
- * request parameters.
2369
- *
2370
- * @since 3.0.0
2371
- *
2372
- * @param string $path The file path.
2373
- *
2374
- * @return The unique code coresponding to the file path.
2375
- */
2376
- function wfu_safe_store_filepath($path) {
2377
- $code = wfu_create_random_string(16);
2378
- $safe_storage = ( WFU_USVAR_exists('wfu_filepath_safe_storage') ? WFU_USVAR('wfu_filepath_safe_storage') : array() );
2379
- $safe_storage[$code] = $path;
2380
- WFU_USVAR_store('wfu_filepath_safe_storage', $safe_storage);
2381
- return $code;
2382
- }
2383
-
2384
- /**
2385
- * Prepare to Batch Store Filepath to Safe.
2386
- *
2387
- * This function assigns a unique code to a file path and stores it to a global
2388
- * variable so that then it is stored in User Space.
2389
- *
2390
- * @since 4.14.3
2391
- *
2392
- * @param string $path The file path.
2393
- *
2394
- * @return The unique code coresponding to the file path.
2395
- */
2396
- function wfu_prepare_to_batch_safe_store_filepath($path) {
2397
- if ( !isset($GLOBALS["WFU_BATCH_PATHS"]) ) $GLOBALS["WFU_BATCH_PATHS"] = array();
2398
- $code = wfu_create_random_string(16);
2399
- $GLOBALS["WFU_BATCH_PATHS"][$code] = $path;
2400
- return $code;
2401
- }
2402
-
2403
- /**
2404
- * Batch Store Filepaths to Safe.
2405
- *
2406
- * This function stores many file paths into the current user's User Space. The
2407
- * batch function is much quicker that wfu_safe_store_filepath() when a large
2408
- * number of file paths needs to be stored, because it makes only one call to
2409
- * the User Space.
2410
- *
2411
- * @since 4.14.3
2412
- */
2413
- function wfu_batch_safe_store_filepaths() {
2414
- if ( !isset($GLOBALS["WFU_BATCH_PATHS"]) ) return;
2415
- $safe_storage = ( WFU_USVAR_exists('wfu_filepath_safe_storage') ? WFU_USVAR('wfu_filepath_safe_storage') : array() );
2416
- foreach ( $GLOBALS["WFU_BATCH_PATHS"] as $code => $path ) $safe_storage[$code] = $path;
2417
- WFU_USVAR_store('wfu_filepath_safe_storage', $safe_storage);
2418
- unset($GLOBALS["WFU_BATCH_PATHS"]);
2419
- }
2420
-
2421
- /**
2422
- * Retrieve Filepath from Safe.
2423
- *
2424
- * This function retrieves a file path, previously stored in current user's User
2425
- * Space, based on its corresponding unique code.
2426
- *
2427
- * @since 3.0.0
2428
- *
2429
- * @param string $code The unique code.
2430
- *
2431
- * @return The file path coresponding to the code.
2432
- */
2433
- function wfu_get_filepath_from_safe($code) {
2434
- //sanitize $code
2435
- $code = wfu_sanitize_code($code);
2436
- if ( $code == "" ) return false;
2437
- //return filepath from session variable, if exists
2438
- if ( !WFU_USVAR_exists('wfu_filepath_safe_storage') ) return false;
2439
- $safe_storage = WFU_USVAR('wfu_filepath_safe_storage');
2440
- if ( !isset($safe_storage[$code]) ) return false;
2441
- return $safe_storage[$code];
2442
- }
2443
-
2444
- /**
2445
- * Check if File Extension is Restricted.
2446
- *
2447
- * This function checks if the extension of a file name is restricted. It also
2448
- * checks for double extensions. This function is not used anymore.
2449
- *
2450
- * @since 3.0.0
2451
- * @deprecated 3.9.0 Use wfu_file_extension_blacklisted()
2452
- * @see wfu_file_extension_blacklisted()
2453
- *
2454
- * @param string $filename The file name to check.
2455
- *
2456
- * @return bool True if extension is restricted, false otherwise.
2457
- */
2458
- function wfu_file_extension_restricted($filename) {
2459
- return (
2460
- substr($filename, -4) == ".php" ||
2461
- substr($filename, -3) == ".js" ||
2462
- substr($filename, -4) == ".pht" ||
2463
- substr($filename, -5) == ".php3" ||
2464
- substr($filename, -5) == ".php4" ||
2465
- substr($filename, -5) == ".php5" ||
2466
- substr($filename, -6) == ".phtml" ||
2467
- substr($filename, -4) == ".htm" ||
2468
- substr($filename, -5) == ".html" ||
2469
- substr($filename, -9) == ".htaccess" ||
2470
- strpos($filename, ".php.") !== false ||
2471
- strpos($filename, ".js.") !== false ||
2472
- strpos($filename, ".pht.") !== false ||
2473
- strpos($filename, ".php3.") !== false ||
2474
- strpos($filename, ".php4.") !== false ||
2475
- strpos($filename, ".php5.") !== false ||
2476
- strpos($filename, ".phtml.") !== false ||
2477
- strpos($filename, ".htm.") !== false ||
2478
- strpos($filename, ".html.") !== false ||
2479
- strpos($filename, ".htaccess.") !== false
2480
- );
2481
- }
2482
-
2483
- /**
2484
- * Convert Time to Human-Readable Format.
2485
- *
2486
- * This function converts a time, given in integer format, into a human-readable
2487
- * one providing number of days, hours, minutes and seconds.
2488
- *
2489
- * @since 4.0.0
2490
- *
2491
- * @param int $time The time to convert.
2492
- *
2493
- * @return string The time in human-readable format.
2494
- */
2495
- function wfu_human_time($time) {
2496
- $time = (int)$time;
2497
- $days = (int)($time/86400);
2498
- $time -= $days * 86400;
2499
- $hours = (int)($time/3600);
2500
- $time -= $hours * 3600;
2501
- $minutes = (int)($time/60);
2502
- $secs = $time - $minutes * 60;
2503
- $human_time = ( $days > 0 ? $days."d" : "" ).( $hours > 0 ? $hours."h" : "" ).( $minutes > 0 ? $minutes."m" : "" ).( $secs > 0 ? $secs."s" : "" );
2504
- if ( $human_time == "" ) $human_time == "0s";
2505
- return $human_time;
2506
- }
2507
-
2508
- /**
2509
- * Convert File Size to Human-Readable Format.
2510
- *
2511
- * This function converts a file size, given in bytes, into a human-readable
2512
- * format providing number of GBs, MBs, KBs and bytes.
2513
- *
2514
- * @since 3.1.0
2515
- *
2516
- * @param int $size The file size in bytes.
2517
- * @param string $unit Optional. The size unit to use. It can be GB, MB, KB. If
2518
- * it is omitted then it will be calculated automatically.
2519
- *
2520
- * @return string The file size in human-readable format.
2521
- */
2522
- function wfu_human_filesize($size, $unit = "") {
2523
- if ( ( !$unit && $size >= 1<<30 ) || $unit == "GB" )
2524
- return number_format($size / (1<<30), 2)."GB";
2525
- if( ( !$unit && $size >= 1<<20 ) || $unit == "MB" )
2526
- return number_format($size / (1<<20), 2)."MB";
2527
- if( ( !$unit && $size >= 1<<10 ) || $unit == "KB" )
2528
- return number_format($size / (1<<10), 2)."KB";
2529
- return number_format($size)." bytes";
2530
- }
2531
-
2532
- /**
2533
- * Check if File Exists Including Chunks.
2534
- *
2535
- * This function checks if a file exists. It will also return true if chunks of
2536
- * a file still uploading exist.
2537
- *
2538
- * @since 4.12.0
2539
- *
2540
- * @param string $path The file path to check.
2541
- *
2542
- * @return bool True if file exists, false otherwise.
2543
- */
2544
- function wfu_file_exists_extended($path) {
2545
- if ( wfu_file_exists($path) ) return true;
2546
-
2547
- return false;
2548
- }
2549
-
2550
- /**
2551
- * Check if File Exists.
2552
- *
2553
- * This function checks if a file exists. It is an extension to the original
2554
- * PHP file_exists() function to take special actions in cases where the file
2555
- * is stored in an sFTP location or perhaps in other external locations (cloud
2556
- * services, WebDAV etc.).
2557
- *
2558
- * @since 3.9.3
2559
- *
2560
- * @redeclarable
2561
- *
2562
- * @param string $path The file path to check.
2563
- * @param string $caller The name of the function that called this one.
2564
- *
2565
- * @return bool True if file exists, false otherwise.
2566
- */
2567
- function wfu_file_exists($path, $caller = null) {
2568
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2569
- //For FTP and SFTP paths this function will be executed only under certain
2570
- //conditions, because it may take a long time.
2571
- //For FTP paths, execution is determined by 2 variables:
2572
- // - WFU_FILEOPERATION_IGNOREFTP: This is a general flag to ignore
2573
- // calculation for all file function.
2574
- // - WFU_FTPFILEEXISTS_DEFVALUE: This is the value returned in case the
2575
- // previous flag is true.
2576
- //If WFU_FTPFILEEXISTS_DEFVALUE starts with an asterisk (*) then it
2577
- //preceeds over the general flag.
2578
- //For SFTP paths there are similar variables.
2579
- if ( substr($path, 0, 6) == "ftp://" ) {
2580
- $ret = false;
2581
- $def = WFU_VAR("WFU_FTPFILEEXISTS_DEFVALUE");
2582
- if ( substr($def, 0, 1) == "*" ) {
2583
- switch ( $def ) {
2584
- case "*true": $ret = true; break;
2585
- case "*false": $ret = false; break;
2586
- case "*calc": $ret = file_exists($path); break;
2587
- }
2588
- }
2589
- else $ret = ( WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") == "true" ? ( $def == "true" ) : file_exists($path) );
2590
- return $ret;
2591
- }
2592
- elseif ( substr($path, 0, 7) == "sftp://" ) {
2593
- $ret = false;
2594
- $def = WFU_VAR("WFU_SFTPFILEEXISTS_DEFVALUE");
2595
- if ( substr($def, 0, 1) == "*" ) {
2596
- switch ( $def ) {
2597
- case "*true": $ret = true; break;
2598
- case "*false": $ret = false; break;
2599
- case "*calc": $ret = wfu_file_exists_sftp($path); break;
2600
- }
2601
- }
2602
- else $ret = ( WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") == "true" ? ( $def == "true" ) : wfu_file_exists_sftp($path) );
2603
- return $ret;
2604
- }
2605
- elseif ( file_exists($path) ) return true;
2606
-
2607
- return false;
2608
- }
2609
-
2610
- /**
2611
- * Get Info About File.
2612
- *
2613
- * This function gets file info. It is an extension to the original PHP stat()
2614
- * function to take special actions in cases where the file is stored in an sFTP
2615
- * location or perhaps in other external locations (cloud services, WebDAV
2616
- * etc.).
2617
- *
2618
- * @since 4.15.0
2619
- *
2620
- * @redeclarable
2621
- *
2622
- * @param string $path The file path to check.
2623
- * @param string $caller The name of the function that called this one.
2624
- *
2625
- * @return array|false Information about the file, or false on error.
2626
- */
2627
- function wfu_stat($path, $caller = null) {
2628
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2629
- if ( substr($path, 0, 6) == "ftp://" ) {
2630
- $ret = array( "mtime" => 0, "size" => 0 );
2631
- $def = WFU_VAR("WFU_FTPSTAT_DEFVALUE");
2632
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2633
- $ret = stat($path);
2634
- return $ret;
2635
- }
2636
- elseif ( substr($path, 0, 7) == "sftp://" ) {
2637
- $ret = array( "mtime" => 0, "size" => 0 );
2638
- $def = WFU_VAR("WFU_SFTPSTAT_DEFVALUE");
2639
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2640
- $ret = wfu_stat_sftp($path);
2641
- return $ret;
2642
- }
2643
- else return stat($path);
2644
- }
2645
-
2646
- /**
2647
- * Get Size of File.
2648
- *
2649
- * This function gets file size. It is an extension to the original PHP
2650
- * filesize() function to take special actions in cases where the file is stored
2651
- * in an sFTP location or perhaps in other external locations (cloud services,
2652
- * WebDAV etc.).
2653
- *
2654
- * @since 4.15.0
2655
- *
2656
- * @redeclarable
2657
- *
2658
- * @param string $path The file path to check.
2659
- * @param string $caller The name of the function that called this one.
2660
- *
2661
- * @return int|false The file size or false on error.
2662
- */
2663
- function wfu_filesize($path, $caller = null) {
2664
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2665
- if ( substr($path, 0, 6) == "ftp://" ) {
2666
- $ret = false;
2667
- $def = WFU_VAR("WFU_FTPFILESIZE_DEFVALUE");
2668
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2669
- $ret = filesize($path);
2670
- return $ret;
2671
- }
2672
- elseif ( substr($path, 0, 7) == "sftp://" ) {
2673
- $ret = false;
2674
- $def = WFU_VAR("WFU_SFTPFILESIZE_DEFVALUE");
2675
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2676
- $ret = wfu_filesize_sftp($path);
2677
- return $ret;
2678
- }
2679
- else return filesize($path);
2680
- }
2681
-
2682
- /**
2683
- * Get File Stream Handle.
2684
- *
2685
- * This function gets a file stream handle. It is an extension to the original
2686
- * PHP fopen() function to take special actions in cases where the file is
2687
- * stored in an sFTP location or perhaps in other external locations (cloud
2688
- * services, WebDAV etc.).
2689
- *
2690
- * @since 4.15.0
2691
- *
2692
- * @redeclarable
2693
- *
2694
- * @param string $path The file path to check.
2695
- * @param string $mode The file access mode.
2696
- * @param string $caller The name of the function that called this one.
2697
- *
2698
- * @return resource|false The file stream handle or false on error.
2699
- */
2700
- function wfu_fopen($path, $mode, $caller = null) {
2701
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2702
- if ( substr($path, 0, 6) == "ftp://" ) {
2703
- $ret = false;
2704
- $def = WFU_VAR("WFU_FTPFOPEN_DEFVALUE");
2705
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2706
- $ret = fopen($path, $mode);
2707
- return $ret;
2708
- }
2709
- elseif ( substr($path, 0, 7) == "sftp://" ) {
2710
- $ret = false;
2711
- $def = WFU_VAR("WFU_SFTPFOPEN_DEFVALUE");
2712
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2713
- $ret = wfu_fopen_sftp($path, $mode);
2714
- return $ret;
2715
- }
2716
- else return fopen($path, $mode);
2717
- }
2718
-
2719
- /**
2720
- * Get File Contents.
2721
- *
2722
- * This function gets the contents of a file. It is an extension to the original
2723
- * PHP file_get_contents() function to take special actions in cases where the
2724
- * file is stored in an sFTP location or perhaps in other external locations
2725
- * (cloud services, WebDAV etc.).
2726
- *
2727
- * @since 4.15.0
2728
- *
2729
- * @redeclarable
2730
- *
2731
- * @param string $path The file path.
2732
- * @param string $caller The name of the function that called this one.
2733
- *
2734
- * @return string|false The file contents as a string or false on error.
2735
- */
2736
- function wfu_file_get_contents($path, $caller = null) {
2737
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2738
- if ( substr($path, 0, 6) == "ftp://" ) {
2739
- $ret = false;
2740
- $def = WFU_VAR("WFU_FTPFILEGETCONTENTS_DEFVALUE");
2741
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2742
- $ret = file_get_contents($path);
2743
- return $ret;
2744
- }
2745
- elseif ( substr($path, 0, 7) == "sftp://" ) {
2746
- $ret = false;
2747
- $def = WFU_VAR("WFU_SFTPFILEGETCONTENTS_DEFVALUE");
2748
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2749
- $ret = wfu_file_get_contents_sftp($path);
2750
- return $ret;
2751
- }
2752
- else return file_get_contents($path);
2753
- }
2754
-
2755
- /**
2756
- * Get MD5 of File.
2757
- *
2758
- * This function gets the md5 signature of a file. It is an extension to the
2759
- * original PHP md5_file() function to take special actions in cases where the
2760
- * file is stored in an sFTP location or perhaps in other external locations
2761
- * (cloud services, WebDAV etc.).
2762
- *
2763
- * @since 4.15.0
2764
- *
2765
- * @redeclarable
2766
- *
2767
- * @param string $path The file path.
2768
- * @param string $caller The name of the function that called this one.
2769
- *
2770
- * @return string|false The md5 of the file or false on error.
2771
- */
2772
- function wfu_md5_file($path, $caller = null) {
2773
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2774
- if ( substr($path, 0, 6) == "ftp://" ) {
2775
- $ret = false;
2776
- $def = WFU_VAR("WFU_FTPMD5FILE_DEFVALUE");
2777
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2778
- $ret = md5_file($path);
2779
- return $ret;
2780
- }
2781
- elseif ( substr($path, 0, 7) == "sftp://" ) {
2782
- $ret = false;
2783
- $def = WFU_VAR("WFU_SFTPMD5FILE_DEFVALUE");
2784
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2785
- $ret = wfu_md5_file_sftp($path);
2786
- return $ret;
2787
- }
2788
- else return md5_file($path);
2789
- }
2790
-
2791
- /**
2792
- * Delete a File.
2793
- *
2794
- * This function deletes a file. It is an extension to the original PHP unlink()
2795
- * function to take special actions in cases where the file is stored in an sFTP
2796
- * location or perhaps in other external locations (cloud services, WebDAV
2797
- * etc.).
2798
- *
2799
- * @since 4.15.0
2800
- *
2801
- * @redeclarable
2802
- *
2803
- * @param string $path The file path.
2804
- * @param string $caller The name of the function that called this one.
2805
- *
2806
- * @return boolean True on success, false on error.
2807
- */
2808
- function wfu_unlink($path, $caller = null) {
2809
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2810
- if ( substr($path, 0, 6) == "ftp://" ) {
2811
- $ret = false;
2812
- $def = WFU_VAR("WFU_FTPUNLINK_DEFVALUE");
2813
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2814
- $ret = unlink($path);
2815
- return $ret;
2816
- }
2817
- elseif ( substr($path, 0, 7) == "sftp://" ) {
2818
- $ret = false;
2819
- $def = WFU_VAR("WFU_SFTPMD5FILE_DEFVALUE");
2820
- if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2821
- $ret = wfu_unlink_sftp($path);
2822
- return $ret;
2823
- }
2824
- else return unlink($path);
2825
- }
2826
-
2827
- /**
2828
- * Get MIME Type of File.
2829
- *
2830
- * This function gets MIME type of a file, using mime_content_type() function if
2831
- * exists, otherwise it uses finfo_open(). If none of them exist it returns a
2832
- * MIME type based on file extension.
2833
- *
2834
- * @since 4.14.3
2835
- *
2836
- * @param int $path The path to the file.
2837
- *
2838
- * @return string The MIME type.
2839
- */
2840
- function wfu_mime_content_type($path) {
2841
- if ( function_exists('mime_content_type') ) {
2842
- $mimetype = mime_content_type($path);
2843
- return $mimetype;
2844
- }
2845
- elseif ( function_exists('finfo_open') ) {
2846
- $finfo = finfo_open(FILEINFO_MIME_TYPE);
2847
- $mimetype = finfo_file($finfo, $path);
2848
- finfo_close($finfo);
2849
- return $mimetype;
2850
- }
2851
- else {
2852
- $mime_types = array(
2853
- 'txt' => 'text/plain',
2854
- 'htm' => 'text/html',
2855
- 'html' => 'text/html',
2856
- 'php' => 'text/html',
2857
- 'css' => 'text/css',
2858
- 'js' => 'application/javascript',
2859
- 'json' => 'application/json',
2860
- 'xml' => 'application/xml',
2861
- 'swf' => 'application/x-shockwave-flash',
2862
- 'flv' => 'video/x-flv',
2863
- // images
2864
- 'png' => 'image/png',
2865
- 'jpe' => 'image/jpeg',
2866
- 'jpeg' => 'image/jpeg',
2867
- 'jpg' => 'image/jpeg',
2868
- 'gif' => 'image/gif',
2869
- 'bmp' => 'image/bmp',
2870
- 'ico' => 'image/vnd.microsoft.icon',
2871
- 'tiff' => 'image/tiff',
2872
- 'tif' => 'image/tiff',
2873
- 'svg' => 'image/svg+xml',
2874
- 'svgz' => 'image/svg+xml',
2875
- // archives
2876
- 'zip' => 'application/zip',
2877
- 'rar' => 'application/x-rar-compressed',
2878
- 'exe' => 'application/x-msdownload',
2879
- 'msi' => 'application/x-msdownload',
2880
- 'cab' => 'application/vnd.ms-cab-compressed',
2881
- // audio/video
2882
- 'mp3' => 'audio/mpeg',
2883
- 'qt' => 'video/quicktime',
2884
- 'mov' => 'video/quicktime',
2885
- // adobe
2886
- 'pdf' => 'application/pdf',
2887
- 'psd' => 'image/vnd.adobe.photoshop',
2888
- 'ai' => 'application/postscript',
2889
- 'eps' => 'application/postscript',
2890
- 'ps' => 'application/postscript',
2891
- // ms office
2892
- 'doc' => 'application/msword',
2893
- 'rtf' => 'application/rtf',
2894
- 'xls' => 'application/vnd.ms-excel',
2895
- 'ppt' => 'application/vnd.ms-powerpoint',
2896
- 'docx' => 'application/msword',
2897
- 'xlsx' => 'application/vnd.ms-excel',
2898
- 'pptx' => 'application/vnd.ms-powerpoint',
2899
- // open office
2900
- 'odt' => 'application/vnd.oasis.opendocument.text',
2901
- 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
2902
- );
2903
- $filename = wfu_basename($path);
2904
- $ext = wfu_fileext($filename);
2905
- if ( array_key_exists($ext, $mime_types) )
2906
- return $mime_types[$ext];
2907
- else return 'application/octet-stream';
2908
- }
2909
- }
2910
-
2911
- /**
2912
- * Custom Attempt to determine the real file type of a file.
2913
- *
2914
- * This is a wrapper function of Wordpress wp_check_filetype_and_ext(), which
2915
- * also takes into account sftp:// filepaths.
2916
- *
2917
- * @since 4.15.0
2918
- *
2919
- * @param string $file Full path to the file.
2920
- * @param string $filename The name of the file.
2921
- *
2922
- * @return array {
2923
- * Values for the extension, mime type, and corrected filename.
2924
- *
2925
- * @type string|false $ext File extension, or false if the file doesn't
2926
- * match a mime type.
2927
- * @type string|false $type File mime type, or false if the file doesn't
2928
- * match a mime type.
2929
- * @type string|false $proper_filename File name with its correct extension,
2930
- * or false if it cannot be determined.
2931
- * }
2932
- */
2933
- function wfu_wp_check_filetype_and_ext( $file, $filename ) {
2934
- //ignore check for sftp files
2935
- if ( substr($file, 0, 7) == "sftp://" ) {
2936
- return array( "proper_filename" => false );
2937
- }
2938
- else return wp_check_filetype_and_ext( $file, $filename );
2939
- }
2940
-
2941
- //********************* User Functions *****************************************
2942
-
2943
- /**
2944
- * Get Matching User Role.
2945
- *
2946
- * This function checks if any of the user's roles are included in a list of
2947
- * roles. If the user is administrator it will match. If 'all' is included in
2948
- * the list of roles then it will also match. The function returns the matched
2949
- * role.
2950
- *
2951
- * @since 2.1.2
2952
- *
2953
- * @param object $user The user to check.
2954
- * @param array $param_roles A list of roles to match the user.
2955
- *
2956
- * @return string The matching role, or 'nomatch'.
2957
- */
2958
- function wfu_get_user_role($user, $param_roles) {
2959
- $result_role = 'nomatch';
2960
- if ( !empty( $user->roles ) && is_array( $user->roles ) ) {
2961
- /* Go through the array of the roles of the current user */
2962
- foreach ( $user->roles as $user_role ) {
2963
- $user_role = strtolower($user_role);
2964
- /* if this role matches to the roles in $param_roles or it is
2965
- administrator or $param_roles allow all roles then it is
2966
- approved */
2967
- if ( in_array($user_role, $param_roles) || $user_role == 'administrator' || in_array('all', $param_roles) ) {
2968
- /* We approve this role of the user and exit */
2969
- $result_role = $user_role;
2970
- break;
2971
- }
2972
- }
2973
- }
2974
- /* if the user has no roles (guest) and guests are allowed, then it is
2975
- approved */
2976
- elseif ( in_array('guests', $param_roles) ) {
2977
- $result_role = 'guest';
2978
- }
2979
- return $result_role;
2980
- }
2981
-
2982
- /**
2983
- * Get Valid User Roles.
2984
- *
2985
- * This function gets all user's valid roles by checking which of them are
2986
- * included in $wp_roles global variable.
2987
- *
2988
- * @since 3.0.0
2989
- *
2990
- * @global array $wp_roles An array of Wordpress roles.
2991
- *
2992
- * @param object $user The user to check.
2993
- *
2994
- * @return array The list of user's valid roles.
2995
- */
2996
- function wfu_get_user_valid_role_names($user) {
2997
- global $wp_roles;
2998
-
2999
- $result_roles = array();
3000
- if ( !empty( $user->roles ) && is_array( $user->roles ) ) {
3001
- /* get all valid roles */
3002
- $roles = $wp_roles->get_names();
3003
- /* Go through the array of the roles of the current user */
3004
- foreach ( $user->roles as $user_role ) {
3005
- $user_role = strtolower($user_role);
3006
- /* If one role of the current user matches to the roles allowed to upload */
3007
- if ( in_array($user_role, array_keys($roles)) ) array_push($result_roles, $user_role);
3008
- }
3009
- }
3010
-
3011
- return $result_roles;
3012
- }
3013
-
3014
- //*********************** DB Functions *****************************************************************************************************
3015
-
3016
- /**
3017
- * Log Action to Database.
3018
- *
3019
- * This function logs plugin's actions (uploads, renames, deletions etc.) in the
3020
- * plugin's database tables. This function stores upload information about all
3021
- * uploaded files.
3022
- *
3023
- * @since 2.4.1
3024
- *
3025
- * @global object $wpdb The Wordpress database object.
3026
- *
3027
- * @param string $action The action to log.
3028
- * @param string $filepath The file path of the involved file.
3029
- * @param int $userid The ID of the user who performs the action.
3030
- * @param string $uploadid The unique ID of the upload, if this is an upload
3031
- * action.
3032
- * @param int $pageid The ID of the upload page, if this is an upload action.
3033
- * @param int $blogid The ID of the blog (in case this is a multisite
3034
- * installation).
3035
- * @param int $sid The plugin ID of the upload form, if this is an upload
3036
- * action.
3037
- * @param array $userdata {
3038
- * Any additional user data to store with the uploaded files.
3039
- *
3040
- * @type array $userdata_field {
3041
- * Individual user data field.
3042
- *
3043
- * @type string $label The title of the userdata field.
3044
- * @type string $value The value entered by the user in the field.
3045
- * }
3046
- * }
3047
- * @param object $filerec Optional. The db record of the file, if available.
3048
- *
3049
- * @return int The ID of the new record that was added in the database, or 0 if
3050
- * no record was added.
3051
- */
3052
- function wfu_log_action($action, $filepath, $userid, $uploadid, $pageid, $blogid, $sid, $userdata, $filerec = null) {
3053
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3054
- global $wpdb;
3055
- $table_name1 = $wpdb->prefix . "wfu_log";
3056
- $table_name2 = $wpdb->prefix . "wfu_userdata";
3057
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
3058
-
3059
- $check_file_existence = true;
3060
- if ( $action == 'datasubmit' || substr($action, 0, 5) == 'other' ) $check_file_existence = false;
3061
- if ( $check_file_existence && !wfu_file_exists($filepath, "wfu_log_action") ) return;
3062
-
3063
- //$parts = pathinfo($filepath);
3064
- $relativepath = wfu_path_abs2rel($filepath);
3065
- // if ( substr($relativepath, 0, 1) != '/' ) $relativepath = '/'.$relativepath;
3066
-
3067
- $retid = 0;
3068
- if ( $action == 'upload' || $action == 'include' || $action == 'datasubmit' ) {
3069
- if ( $action == 'upload' || $action == 'include' ) {
3070
- // calculate and store file hash if this setting is enabled from Settings
3071
- $filehash = '';
3072
- if ( $plugin_options['hashfiles'] == '1' ) $filehash = wfu_md5_file($filepath, "wfu_log_action");
3073
- // calculate file size
3074
- $filesize = wfu_filesize($filepath, "wfu_log_action");
3075
- // first make obsolete records having the same file path because the old file has been replaced
3076
- $oldrecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE filepath = \''.esc_sql($relativepath).'\' AND date_to = 0');
3077
- if ( $oldrecs ) {
3078
- foreach ( $oldrecs as $oldrec ) wfu_make_rec_obsolete($oldrec);
3079
- }
3080
- }
3081
- // attempt to create new log record
3082
- $now_date = date('Y-m-d H:i:s');
3083
- if ( $wpdb->insert($table_name1,
3084
- array(
3085
- 'userid' => $userid,
3086
- 'uploaduserid' => $userid,
3087
- 'uploadtime' => time(),
3088
- 'sessionid' => wfu_get_session_id(),
3089
- 'filepath' => ( $action == 'datasubmit' ? '' : $relativepath ),
3090
- 'filehash' => ( $action == 'datasubmit' ? '' : $filehash ),
3091
- 'filesize' => ( $action == 'datasubmit' ? 0 : $filesize ),
3092
- 'uploadid' => $uploadid,
3093
- 'pageid' => $pageid,
3094
- 'blogid' => $blogid,
3095
- 'sid' => $sid,
3096
- 'date_from' => $now_date,
3097
- 'date_to' => 0,
3098
- 'action' => $action
3099
- ),
3100
- array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s' )) !== false ) {
3101
- $retid = $wpdb->insert_id;
3102
- // if new log record has been created, also create user data records
3103
- if ( $userdata != null && $uploadid != '' ) {
3104
- foreach ( $userdata as $userdata_key => $userdata_field ) {
3105
- $existing = $wpdb->get_row('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$uploadid.'\' AND property = \''.esc_sql($userdata_field['label']).'\' AND date_to = 0');
3106
- if ($existing == null)
3107
- $wpdb->insert($table_name2,
3108
- array(
3109
- 'uploadid' => $uploadid,
3110
- 'property' => $userdata_field['label'],
3111
- 'propkey' => $userdata_key,
3112
- 'propvalue' => $userdata_field['value'],
3113
- 'date_from' => $now_date,
3114
- 'date_to' => 0
3115
- ),
3116
- array( '%s', '%s', '%d', '%s', '%s', '%s' ));
3117
- }
3118
- }
3119
- }
3120
- }
3121
- //for rename or move action the $action variable is of the form:
3122
- // $action = 'rename:'.$newfilepath; (for rename action)
3123
- // $action = 'move:'.$newfilepath; (for move action)
3124
- //in order to pass the new file path
3125
- elseif ( substr($action, 0, 6) == 'rename' || substr($action, 0, 4) == 'move' ) {
3126
- $cleanaction = ( substr($action, 0, 6) == 'rename' ? 'rename' : 'move' );
3127
- //get new filepath
3128
- $newfilepath = substr($action, strlen($cleanaction) + 1);
3129
- $relativepath = wfu_path_abs2rel($newfilepath);
3130
- // if ( substr($relativepath, 0, 1) != '/' ) $relativepath = '/'.$relativepath;
3131
- //get stored file data from database without user data
3132
- $filerec = wfu_get_file_rec($filepath, false);
3133
- //log action only if there are previous stored file data
3134
- if ( $filerec != null ) {
3135
- $now_date = date('Y-m-d H:i:s');
3136
- //make previous record obsolete
3137
- $wpdb->update($table_name1,
3138
- array( 'date_to' => $now_date ),
3139
- array( 'idlog' => $filerec->idlog ),
3140
- array( '%s' ),
3141
- array( '%d' )
3142
- );
3143
- //insert new rename record
3144
- if ( $wpdb->insert($table_name1,
3145
- array(
3146
- 'userid' => $userid,
3147
- 'uploaduserid' => $filerec->uploaduserid,
3148
- 'uploadtime' => $filerec->uploadtime,
3149
- 'sessionid' => $filerec->sessionid,
3150
- 'filepath' => $relativepath,
3151
- 'filehash' => $filerec->filehash,
3152
- 'filesize' => $filerec->filesize,
3153
- 'uploadid' => $filerec->uploadid,
3154
- 'pageid' => $filerec->pageid,
3155
- 'blogid' => $filerec->blogid,
3156
- 'sid' => $filerec->sid,
3157
- 'date_from' => $now_date,
3158
- 'date_to' => 0,
3159
- 'action' => $cleanaction,
3160
- 'linkedto' => $filerec->idlog,
3161
- 'filedata' => $filerec->filedata
3162
- ),
3163
- array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' ) ) !== false )
3164
- $retid = $wpdb->insert_id;
3165
- }
3166
- }
3167
- elseif ( $action == 'delete' ) {
3168
- //get stored file data from database without user data
3169
- if ( $filerec == null ) $filerec = wfu_get_file_rec($filepath, false);
3170
- //log action only if there are previous stored file data
3171
- if ( $filerec != null ) {
3172
- $now_date = date('Y-m-d H:i:s');
3173
- //make previous record obsolete
3174
- $wpdb->update($table_name1,
3175
- array( 'date_to' => $now_date ),
3176
- array( 'idlog' => $filerec->idlog ),
3177
- array( '%s' ),
3178
- array( '%d' )
3179
- );
3180
- //insert new delete record
3181
- if ( $wpdb->insert($table_name1,
3182
- array(
3183
- 'userid' => $userid,
3184
- 'uploaduserid' => $filerec->uploaduserid,
3185
- 'uploadtime' => $filerec->uploadtime,
3186
- 'sessionid' => $filerec->sessionid,
3187
- 'filepath' => $filerec->filepath,
3188
- 'filehash' => $filerec->filehash,
3189
- 'filesize' => $filerec->filesize,
3190
- 'uploadid' => $filerec->uploadid,
3191
- 'pageid' => $filerec->pageid,
3192
- 'blogid' => $filerec->blogid,
3193
- 'sid' => $filerec->sid,
3194
- 'date_from' => $now_date,
3195
- 'date_to' => $now_date,
3196
- 'action' => 'delete',
3197
- 'linkedto' => $filerec->idlog,
3198
- 'filedata' => $filerec->filedata
3199
- ),
3200
- array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' )) != false )
3201
- $retid = $wpdb->insert_id;
3202
- }
3203
- }
3204
- elseif ( $action == 'download' ) {
3205
- //get stored file data from database without user data
3206
- $filerec = wfu_get_file_rec($filepath, false);
3207
- //log action only if there are previous stored file data
3208
- if ( $filerec != null ) {
3209
- $now_date = date('Y-m-d H:i:s');
3210
- //make previous record obsolete
3211
- $wpdb->update($table_name1,
3212
- array( 'date_to' => $now_date ),
3213
- array( 'idlog' => $filerec->idlog ),
3214
- array( '%s' ),
3215
- array( '%d' )
3216
- );
3217
- //insert new download record
3218
- if ( $wpdb->insert($table_name1,
3219
- array(
3220
- 'userid' => $userid,
3221
- 'uploaduserid' => $filerec->uploaduserid,
3222
- 'uploadtime' => $filerec->uploadtime,
3223
- 'sessionid' => $filerec->sessionid,
3224
- 'filepath' => $filerec->filepath,
3225
- 'filehash' => $filerec->filehash,
3226
- 'filesize' => $filerec->filesize,
3227
- 'uploadid' => $filerec->uploadid,
3228
- 'pageid' => $filerec->pageid,
3229
- 'blogid' => $filerec->blogid,
3230
- 'sid' => $filerec->sid,
3231
- 'date_from' => $now_date,
3232
- 'date_to' => 0,
3233
- 'action' => 'download',
3234
- 'linkedto' => $filerec->idlog,
3235
- 'filedata' => $filerec->filedata
3236
- ),
3237
- array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' )) != false )
3238
- $retid = $wpdb->insert_id;
3239
- }
3240
- }
3241
- //for modify action the $action variable is of the form: $action = 'modify:'.$now_date; in order to pass the exact modify date
3242
- elseif ( substr($action, 0, 6) == 'modify' ) {
3243
- $now_date = substr($action, 7);
3244
- //get stored file data from database without user data
3245
- $filerec = wfu_get_file_rec($filepath, false);
3246
- //log action only if there are previous stored file data
3247
- if ( $filerec != null ) {
3248
- //make previous record obsolete
3249
- $wpdb->update($table_name1,
3250
- array( 'date_to' => $now_date ),
3251
- array( 'idlog' => $filerec->idlog ),
3252
- array( '%s' ),
3253
- array( '%d' )
3254
- );
3255
- //insert new modify record
3256
- if ( $wpdb->insert($table_name1,
3257
- array(
3258
- 'userid' => $userid,
3259
- 'uploaduserid' => $filerec->uploaduserid,
3260
- 'uploadtime' => $filerec->uploadtime,
3261
- 'sessionid' => $filerec->sessionid,
3262
- 'filepath' => $filerec->filepath,
3263
- 'filehash' => $filerec->filehash,
3264
- 'filesize' => $filerec->filesize,
3265
- 'uploadid' => $filerec->uploadid,
3266
- 'pageid' => $filerec->pageid,
3267
- 'blogid' => $filerec->blogid,
3268
- 'sid' => $filerec->sid,
3269
- 'date_from' => $now_date,
3270
- 'date_to' => 0,
3271
- 'action' => 'modify',
3272
- 'linkedto' => $filerec->idlog,
3273
- 'filedata' => $filerec->filedata
3274
- ),
3275
- array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' )) != false )
3276
- $retid = $wpdb->insert_id;
3277
- }
3278
- }
3279
- elseif ( substr($action, 0, 10) == 'changeuser' ) {
3280
- $new_user = substr($action, 11);
3281
- //get stored file data from database without user data
3282
- $filerec = wfu_get_file_rec($filepath, false);
3283
- //log action only if there are previous stored file data
3284
- if ( $filerec != null ) {
3285
- $now_date = date('Y-m-d H:i:s');
3286
- //make previous record obsolete
3287
- $wpdb->update($table_name1,
3288
- array( 'date_to' => $now_date ),
3289
- array( 'idlog' => $filerec->idlog ),
3290
- array( '%s' ),
3291
- array( '%d' )
3292
- );
3293
- //insert new modify record
3294
- if ( $wpdb->insert($table_name1,
3295
- array(
3296
- 'userid' => $userid,
3297
- 'uploaduserid' => $new_user,
3298
- 'uploadtime' => $filerec->uploadtime,
3299
- 'sessionid' => $filerec->sessionid,
3300
- 'filepath' => $filerec->filepath,
3301
- 'filehash' => $filerec->filehash,
3302
- 'filesize' => $filerec->filesize,
3303
- 'uploadid' => $filerec->uploadid,
3304
- 'pageid' => $filerec->pageid,
3305
- 'blogid' => $filerec->blogid,
3306
- 'sid' => $filerec->sid,
3307
- 'date_from' => $now_date,
3308
- 'date_to' => 0,
3309
- 'action' => 'changeuser',
3310
- 'linkedto' => $filerec->idlog,
3311
- 'filedata' => $filerec->filedata
3312
- ),
3313
- array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' )) != false )
3314
- $retid = $wpdb->insert_id;
3315
- }
3316
- }
3317
- elseif ( substr($action, 0, 5) == 'other' ) {
3318
- $info = substr($action, 6);
3319
- $now_date = date('Y-m-d H:i:s');
3320
- //insert new other type record
3321
- if ( $wpdb->insert($table_name1,
3322
- array(
3323
- 'userid' => $userid,
3324
- 'uploaduserid' => -1,
3325
- 'uploadtime' => 0,
3326
- 'sessionid' => '',
3327
- 'filepath' => $info,
3328
- 'filehash' => '',
3329
- 'filesize' => 0,
3330
- 'uploadid' => '',
3331
- 'pageid' => 0,
3332
- 'blogid' => 0,
3333
- 'sid' => '',
3334
- 'date_from' => $now_date,
3335
- 'date_to' => $now_date,
3336
- 'action' => 'other',
3337
- 'linkedto' => -1
3338
- ),
3339
- array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d' )) != false )
3340
- $retid = $wpdb->insert_id;
3341
- }
3342
- return $retid;
3343
- }
3344
-
3345
- /**
3346
- * Revert Database Log Action.
3347
- *
3348
- * This function reverts an action that was recently added in the database. It
3349
- * will also make effective the before-the-last one.
3350
- *
3351
- * @since 2.4.1
3352
- *
3353
- * @global object $wpdb The Wordpress database object.
3354
- *
3355
- * @param int $idlog The ID of the database record to revert.
3356
- */
3357
- function wfu_revert_log_action($idlog) {
3358
- global $wpdb;
3359
- $table_name1 = $wpdb->prefix . "wfu_log";
3360
-
3361
- $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3362
- if ( $filerec != null ) {
3363
- $prevfilerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$filerec->linkedto);
3364
- if ( $prevfilerec != null ) {
3365
- $wpdb->delete($table_name1,
3366
- array( 'idlog' => $filerec->idlog ),
3367
- array( '%d' )
3368
- );
3369
- $wpdb->update($table_name1,
3370
- array( 'date_to' => 0 ),
3371
- array( 'idlog' => $prevfilerec->idlog ),
3372
- array( '%s' ),
3373
- array( '%d' )
3374
- );
3375
- }
3376
- }
3377
- }
3378
-
3379
- /**
3380
- * Get User Name by ID.
3381
- *
3382
- * This function retrieves a user's username by its ID. It will always return a
3383
- * non-empty username, even if user is not found.
3384
- *
3385
- * @since 2.4.1
3386
- *
3387
- * @redeclarable
3388
- *
3389
- * @param int $id The ID of the user.
3390
- *
3391
- * @return string The username.
3392
- */
3393
- function wfu_get_username_by_id($id) {
3394
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3395
- $user = get_user_by('id', $id);
3396
- if ( $user == false && $id > 0 ) $username = 'unknown';
3397
- elseif ( $user == false && $id == -999 ) $username = 'system';
3398
- elseif ( $user == false ) $username = 'guest';
3399
- else $username = $user->user_login;
3400
- return $username;
3401
- }
3402
-
3403
- /**
3404
- * Get Number of Unread Files.
3405
- *
3406
- * This function retrieves the number of uploaded files that have not been read
3407
- * by the administrator (admin has not opened Uploaded Files page in Dashboard
3408
- * to review them).
3409
- *
3410
- * @since 4.7.0
3411
- *
3412
- * @global object $wpdb The Wordpress database object.
3413
- *
3414
- * @redeclarable
3415
- *
3416
- * @return int The number of unread files.
3417
- */
3418
- function wfu_get_unread_files_count() {
3419
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3420
- global $wpdb;
3421
- $table_name1 = $wpdb->prefix . "wfu_log";
3422
-
3423
- //get the last idlog read from options; create the option if it does not
3424
- //exist pointing to the currently last idlog
3425
- $last_idlog = get_option( "wordpress_file_upload_last_idlog" );
3426
- if ( $last_idlog === false ) {
3427
- $latest_idlog = $wpdb->get_var('SELECT MAX(idlog) FROM '.$table_name1);
3428
- $last_idlog = array( 'pre' => $latest_idlog, 'post' => $latest_idlog, 'time' => time() );
3429
- update_option( "wordpress_file_upload_last_idlog", $last_idlog );
3430
- }
3431
- $limit = (int)WFU_VAR("WFU_UPLOADEDFILES_RESET_TIME");
3432
- $unread_files_count = 0;
3433
- if ( $limit == -1 || time() > $last_idlog["time"] + $limit ) $unread_files_count = wfu_get_new_files_count($last_idlog["post"]);
3434
- else $unread_files_count = wfu_get_new_files_count($last_idlog["pre"]);
3435
-
3436
- return $unread_files_count;
3437
- }
3438
-
3439
- /**
3440
- * Get Number of New Uploaded Files.
3441
- *
3442
- * This function retrieves the number of newly uploaded files by counting how
3443
- * many where uploaded after a specific database record ID.
3444
- *
3445
- * @since 4.8.0
3446
- *
3447
- * @global object $wpdb The Wordpress database object.
3448
- *
3449
- * @redeclarable
3450
- *
3451
- * @param int $last_idlog The database record ID which is the base for counting.
3452
- *
3453
- * @return int The number of new uploaded files.
3454
- */
3455
- function wfu_get_new_files_count($last_idlog) {
3456
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3457
- global $wpdb;
3458
- $table_name1 = $wpdb->prefix . "wfu_log";
3459
- return $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1.' WHERE action = \'upload\' AND idlog > '.(int)$last_idlog);
3460
- }
3461
-
3462
- /**
3463
- * Decode Raw File Transfers Log Data.
3464
- *
3465
- * This function converts raw file transfers log data stored in filedata field
3466
- * of a file's database record into a structured array.
3467
- *
3468
- * @since 4.9.0
3469
- *
3470
- * @redeclarable
3471
- *
3472
- * @param string $data The raw log data.
3473
- *
3474
- * @return array {
3475
- * An array of file transfers log information.
3476
- *
3477
- * $type string $service The cloud service used for the file transfer.
3478
- * $type bool $transferred True if the file transfer was successful.
3479
- * $type string $error Error message if the file transfer failed.
3480
- * $type string $destination The destination path of the transfer.
3481
- * $type string $new_filename The new file name of the transferred file.
3482
- * }
3483
- */
3484
- function wfu_read_log_data($data) {
3485
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3486
- $ret['service'] = "";
3487
- $ret['transferred'] = "";
3488
- $ret['error'] = "";
3489
- $ret['destination'] = "";
3490
- $ret['new_filename'] = "";
3491
- if ( substr($data, 0, 5) == "json:" ) {
3492
- $logdata = json_decode(substr($data, 5), true);
3493
- $ret['service'] = $logdata["service"];
3494
- $ret['transferred'] = $logdata["transferred"];
3495
- $ret['error'] = $logdata["error"];
3496
- $ret['destination'] = $logdata["destination"];
3497
- $ret['new_filename'] = $logdata["new_filename"];
3498
- }
3499
- else list($ret['service'], $ret['destination']) = explode("|", $data);
3500
-
3501
- return $ret;
3502
- }
3503
-
3504
- /**
3505
- * Get Database File Record From File Path.
3506
- *
3507
- * This function gets the most current database record of an uploaded file from
3508
- * its path and also includes any userdata.
3509
- *
3510
- * @since 2.4.1
3511
- *
3512
- * @global object $wpdb The Wordpress database object.
3513
- *
3514
- * @param string $filepath The path of the file.
3515
- * @param bool $include_userdata Include any userdata information in the
3516
- * returned record.
3517
- *
3518
- * @return object|null The database object of the file, or null if it is not
3519
- * found.
3520
- */
3521
- function wfu_get_file_rec($filepath, $include_userdata) {
3522
- global $wpdb;
3523
- $table_name1 = $wpdb->prefix . "wfu_log";
3524
- $table_name2 = $wpdb->prefix . "wfu_userdata";
3525
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
3526
-
3527
- if ( !wfu_file_exists($filepath, "wfu_get_file_rec") ) return null;
3528
-
3529
- $relativepath = wfu_path_abs2rel($filepath);
3530
- // if ( substr($relativepath, 0, 1) != '/' ) $relativepath = '/'.$relativepath;
3531
- //if file hash is enabled, then search file based on its path and hash, otherwise find file based on its path and size
3532
- if ( isset($plugin_options['hashfiles']) && $plugin_options['hashfiles'] == '1' ) {
3533
- $filehash = wfu_md5_file($filepath, "wfu_get_file_rec");
3534
- $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE filepath = \''.esc_sql($relativepath).'\' AND filehash = \''.$filehash.'\' AND date_to = 0 ORDER BY date_from DESC');
3535
- }
3536
- else {
3537
- $stat = wfu_stat($filepath, "wfu_get_file_rec");
3538
- $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE filepath = \''.esc_sql($relativepath).'\' AND filesize = '.$stat['size'].' AND date_to = 0 ORDER BY date_from DESC');
3539
- }
3540
- //get user data
3541
- if ( $filerec != null && $include_userdata ) {
3542
- $filerec->userdata = null;
3543
- if ( $filerec->uploadid != '' ) {
3544
- $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
3545
- }
3546
- }
3547
- return $filerec;
3548
- }
3549
-
3550
- /**
3551
- * Get Valid Files From a List of Database Records.
3552
- *
3553
- * This function checks which records in a given list of database records of
3554
- * uploaded files contain valid files and returns their file paths.
3555
- *
3556
- * @since 4.9.1
3557
- *
3558
- * @param array $recs An array of database records of uploaded files.
3559
- *
3560
- * @return array An array of file paths of valid files.
3561
- */
3562
- function wfu_get_valid_affected_files($recs) {
3563
- $valid_affected_files = array();
3564
- $files_checked = array();
3565
- foreach ($recs as $rec)
3566
- if ( $latestrec = wfu_get_latest_rec_from_id($rec->idlog) ) {
3567
- $file = wfu_path_rel2abs($latestrec->filepath);
3568
- if ( !in_array($file, $files_checked) ) {
3569
- if ( wfu_file_exists($file, "wfu_get_valid_affected_files") ) array_push($valid_affected_files, $file);
3570
- array_push($files_checked, $file);
3571
- }
3572
- }
3573
-
3574
- return $valid_affected_files;
3575
- }
3576
-
3577
- /**
3578
- * Get Database File Record From Record ID.
3579
- *
3580
- * This function gets the database record of an uploaded file from its record ID
3581
- * and also includes any userdata.
3582
- *
3583
- * @since 3.9.4
3584
- *
3585
- * @global object $wpdb The Wordpress database object.
3586
- *
3587
- * @param int $idlog The database record ID.
3588
- * @param bool $include_userdata Optional. Include any userdata information in
3589
- * the returned record.
3590
- *
3591
- * @return object|null The database object of the file, or null if it is not
3592
- * found.
3593
- */
3594
- function wfu_get_file_rec_from_id($idlog, $include_userdata = false) {
3595
- global $wpdb;
3596
- $table_name1 = $wpdb->prefix . "wfu_log";
3597
- $table_name2 = $wpdb->prefix . "wfu_userdata";
3598
-
3599
- $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3600
- if ( $filerec != null && $include_userdata ) {
3601
- $filerec->userdata = null;
3602
- if ( $filerec->uploadid != '' ) {
3603
- $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
3604
- }
3605
- }
3606
-
3607
- return $filerec;
3608
- }
3609
-
3610
- /**
3611
- * Get Userdata of Uploaded File by Database Record ID.
3612
- *
3613
- * This function gets the userdata (if any) of an uploaded file from its
3614
- * database record ID.
3615
- *
3616
- * @since 4.6.0
3617
- *
3618
- * @param int $idlog The database record ID.
3619
- *
3620
- * @return array {
3621
- * An array of userdata.
3622
- *
3623
- * @type $arrayitem {
3624
- * An individual userdata field.
3625
- *
3626
- * @type string $property The title of the userdata field.
3627
- * @type string $value The value entered by the user in the field.
3628
- * }
3629
- * }
3630
- */
3631
- function wfu_get_userdata_from_id($idlog) {
3632
- $userdata = array();
3633
- $filerec = wfu_get_file_rec_from_id($idlog, true);
3634
- if ( $filerec != null && $filerec->userdata != null )
3635
- foreach ( $filerec->userdata as $item ) {
3636
- $arrayitem = array(
3637
- "property" => $item->property,
3638
- "value" => $item->propvalue
3639
- );
3640
- array_push($userdata, $arrayitem);
3641
- }
3642
-
3643
- return $userdata;
3644
- }
3645
-
3646
- /**
3647
- * Get Oldest Database Record From Unique ID.
3648
- *
3649
- * Every file upload has a unique ID. This unique ID remains the same for any
3650
- * consecutive operations that happen on the file (renaming, transfer, deletion
3651
- * etc.). This function gets the oldest (first) record related to this unique
3652
- * ID, which is usually an 'upload' or 'include' action.
3653
- *
3654
- * @since 4.10.0
3655
- *
3656
- * @global object $wpdb The Wordpress database object.
3657
- *
3658
- * @param string $uniqueid The unique ID of the upload.
3659
- *
3660
- * @return object|null The oldest database record, or null if not found.
3661
- */
3662
- function wfu_get_oldestrec_from_uniqueid($uniqueid) {
3663
- global $wpdb;
3664
- $table_name1 = $wpdb->prefix . "wfu_log";
3665
- $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE idlog IN (SELECT MIN(idlog) FROM '.$table_name1.' WHERE uploadid = \''.$uniqueid.'\')');
3666
- if ( $filerecs == null ) return null;
3667
- if ( count($filerecs) > 0 ) return $filerecs[0];
3668
- else return null;
3669
- }
3670
-
3671
- /**
3672
- * Get Latest Database Record From Record ID.
3673
- *
3674
- * This function gets the most recend (latest) record of a linked series of
3675
- * database upload records having the same unique ID. Every record is linked to
3676
- * its newer one through 'linkedto' field.
3677
- *
3678
- * @since 4.2.0
3679
- *
3680
- * @global object $wpdb The Wordpress database object.
3681
- *
3682
- * @param int $idlog The database record ID.
3683
- *
3684
- * @return object|null The latest database record, or null if not found.
3685
- */
3686
- function wfu_get_latest_rec_from_id($idlog) {
3687
- global $wpdb;
3688
- $table_name1 = $wpdb->prefix . "wfu_log";
3689
- $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3690
- while ( $filerec != null && $filerec->date_to != "0000-00-00 00:00:00" )
3691
- $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE linkedto = '.$filerec->idlog);
3692
-
3693
- return $filerec;
3694
- }
3695
-
3696
- /**
3697
- * Get Newer Linked Database Records From Record ID.
3698
- *
3699
- * This function gets the newer records of a linked series of database upload
3700
- * records having the same unique ID. Every record is linked to its newer one
3701
- * through 'linkedto' field.
3702
- *
3703
- * @since 4.7.0
3704
- *
3705
- * @global object $wpdb The Wordpress database object.
3706
- *
3707
- * @param int $idlog The database record ID.
3708
- *
3709
- * @return array An array of newer linked database records.
3710
- */
3711
- function wfu_get_rec_new_history($idlog) {
3712
- global $wpdb;
3713
- $table_name1 = $wpdb->prefix . "wfu_log";
3714
- $filerecs = array();
3715
- $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3716
- while ( $filerec != null ) {
3717
- array_push($filerecs, $filerec);
3718
- $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE linkedto = '.$filerec->idlog);
3719
- }
3720
-
3721
- return $filerecs;
3722
- }
3723
-
3724
- /**
3725
- * Get Older Linked Database Records From Record ID.
3726
- *
3727
- * This function gets the older records of a linked series of database upload
3728
- * records having the same unique ID. Every record is linked to its newer one
3729
- * through 'linkedto' field.
3730
- *
3731
- * @since 4.7.0
3732
- *
3733
- * @global object $wpdb The Wordpress database object.
3734
- *
3735
- * @param int $idlog The database record ID.
3736
- *
3737
- * @return array An array of older linked database records.
3738
- */
3739
- function wfu_get_rec_old_history($idlog) {
3740
- global $wpdb;
3741
- $table_name1 = $wpdb->prefix . "wfu_log";
3742
- $filerecs = array();
3743
- $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3744
- while ( $filerec != null ) {
3745
- array_push($filerecs, $filerec);
3746
- $filerec = ( $filerec->linkedto > 0 ? $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$filerec->linkedto) : null );
3747
- }
3748
-
3749
- return $filerecs;
3750
- }
3751
-
3752
- /**
3753
- * Get Latest Filedata Properties From Database Record ID
3754
- *
3755
- * This function uses an uploaded file's database record ID to return the
3756
- * filedata property of the corresponding record of the file in the database
3757
- * holding data about its transfer to a service account like Dropbox, provided
3758
- * that this record is still valid. If the record does not exist or exists but
3759
- * it is absolete, then the function returns null, otherwise it returns an
3760
- * array.
3761
- *
3762
- * The [$service]["filepath"] item of the array is set to the final $filepath
3763
- * of the file, in case that the original filename was renamed.
3764
- *
3765
- * @since 4.2.0
3766
- *
3767
- * @param int $idlog Database record ID of the uploaded file.
3768
- * @param bool $is_new Optional. It must be true if the function is called
3769
- * during addition of a new file.
3770
- *
3771
- * @return array|null Returns the filedata array or null if it is not found.
3772
- */
3773
- function wfu_get_latest_filedata_from_id($idlog, $is_new = false) {
3774
- //get latest database record of file, if it is still valid
3775
- $filerec = wfu_get_latest_rec_from_id($idlog);
3776
- //return null if the record does not exist or it is obsolete
3777
- if ( $filerec == null ) return null;
3778
-
3779
- return wfu_get_filedata_from_rec($filerec, $is_new, true, false);
3780
- }
3781
-
3782
- /**
3783
- * Get Filedata Properties From File Path
3784
- *
3785
- * This function uses an uploaded file's path to return the filedata property of
3786
- * the corresponding record of the file in the database holding data about its
3787
- * transfer to a service account like Dropbox, provided that this record is
3788
- * still valid.
3789
- *
3790
- * @since 4.2.0
3791
- *
3792
- * @param string $filepath The path of the uploaded file.
3793
- * @param bool $include_general_data Optional. Determines whether general upload
3794
- * data will be included in the returned filedata structure.
3795
- *
3796
- * @return array|null Returns the filedata array or null if it is not found.
3797
- */
3798
- function wfu_get_filedata($filepath, $include_general_data = false) {
3799
- $filerec = wfu_get_file_rec($filepath, false);
3800
- if ( $filerec == null ) return null;
3801
-
3802
- return wfu_get_filedata_from_rec($filerec, true, false, $include_general_data);
3803
- }
3804
-
3805
- /**
3806
- * Get Filedata Properties From Database Record
3807
- *
3808
- * This function uses an uploaded file's database record to return the filedata
3809
- * property of the corresponding record of the file in the database holding data
3810
- * about its transfer to a service account like Dropbox, provided that this
3811
- * record is still valid.
3812
- *
3813
- * @since 4.3.0
3814
- *
3815
- * @param object $filerec The database record of the uploaded file.
3816
- * @param bool $is_new Optional. It must be true if the function is called
3817
- * during addition of a new file.
3818
- * @param bool $update_transfer Optional. Update filepath property in filedata
3819
- * of "transfer" type, if service records exist.
3820
- * @param bool $include_general_data Optional. Determines whether general upload
3821
- * data will be included in the returned filedata structure.
3822
- *
3823
- * @return array|null Returns the filedata array or null if it is not found.
3824
- */
3825
- function wfu_get_filedata_from_rec($filerec, $is_new = false, $update_transfer = false, $include_general_data = false) {
3826
- //return filedata, if it does not exist and we do not want to create a new
3827
- //filedata structure return null, otherwise return an empty array
3828
- if ( !isset($filerec->filedata) || is_null($filerec->filedata) ) $filedata = ( $is_new ? array() : null );
3829
- else {
3830
- $filedata = wfu_decode_array_from_string($filerec->filedata);
3831
- if ( !is_array($filedata) ) $filedata = ( $is_new ? array() : null );
3832
- }
3833
- if ( !is_null($filedata) ) {
3834
- //update filepath property in filedata of "transfer" type, if service
3835
- //records exist
3836
- if ( $update_transfer ) {
3837
- foreach ( $filedata as $key => $data )
3838
- if ( !isset($data["type"]) || $data["type"] == "transfer" )
3839
- $filedata[$key]["filepath"] = $filerec->filepath;
3840
- }
3841
- //add idlog in filedata if $include_general_data is true
3842
- if ( $include_general_data )
3843
- $filedata["general"] = array(
3844
- "type" => "data",
3845
- "idlog" => $filerec->idlog
3846
- );
3847
- }
3848
-
3849
- return $filedata;
3850
- }
3851
-
3852
- /**
3853
- * Save Filedata To File Database Record
3854
- *
3855
- * This function updates the filedata field of the database record of an
3856
- * uploaded file.
3857
- *
3858
- * @since 4.2.0
3859
- *
3860
- * @global object $wpdb The Wordpress database object.
3861
- *
3862
- * @param int $idlog The database record ID of the uploaded file to be updated.
3863
- * @param array $filedata The new filedata structure to store.
3864
- * @param bool $store_in_latest_rec Optional. Store in the latest linked
3865
- * database record and not the current one.
3866
- *
3867
- * @return bool|int Returns false if errors, or the number of rows affected if
3868
- * successful.
3869
- */
3870
- function wfu_save_filedata_from_id($idlog, $filedata, $store_in_latest_rec = true) {
3871
- global $wpdb;
3872
- $table_name1 = $wpdb->prefix . "wfu_log";
3873
- if ( $store_in_latest_rec ) {
3874
- $latestrec = wfu_get_latest_rec_from_id($idlog);
3875
- $idlog = $latestrec->idlog;
3876
- }
3877
- return $wpdb->update($table_name1, array( 'filedata' => wfu_encode_array_to_string($filedata) ), array( 'idlog' => $idlog ), array( '%s' ), array( '%d' ));
3878
- }
3879
-
3880
- /**
3881
- * Get Userdata of Uploaded File From Database Record.
3882
- *
3883
- * This function gets the database record of an uploaded file from its database
3884
- * record.
3885
- *
3886
- * @since 4.7.0
3887
- *
3888
- * @see wfu_get_userdata_from_id() For more information on the response array
3889
- * format.
3890
- *
3891
- * @global object $wpdb The Wordpress database object.
3892
- *
3893
- * @param object $filerec The database record of the uploaded file.
3894
- *
3895
- * @return array An array of userdata.
3896
- */
3897
- function wfu_get_userdata_from_rec($filerec) {
3898
- global $wpdb;
3899
- $table_name2 = $wpdb->prefix . "wfu_userdata";
3900
-
3901
- $userdata = array();
3902
- if ( $filerec->uploadid != '' ) {
3903
- $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
3904
- if ( $filerec->userdata != null )
3905
- foreach ( $filerec->userdata as $item ) {
3906
- array_push($userdata, $item);
3907
- }
3908
- }
3909
-
3910
- return $userdata;
3911
- }
3912
-
3913
- /**
3914
- * Get Userdata of Uploaded File From Unique ID.
3915
- *
3916
- * This function gets the database record of an uploaded file from the unique ID
3917
- * of the upload.
3918
- *
3919
- * @since 3.11.0
3920
- *
3921
- * @global object $wpdb The Wordpress database object.
3922
- *
3923
- * @param string $uploadid The unique ID of the upload.
3924
- *
3925
- * @return object|null A userdata database record or null if not found.
3926
- */
3927
- function wfu_get_userdata_from_uploadid($uploadid) {
3928
- global $wpdb;
3929
- $table_name2 = $wpdb->prefix . "wfu_userdata";
3930
- $userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$uploadid.'\' AND date_to = 0 ORDER BY propkey');
3931
-
3932
- return $userdata;
3933
- }
3934
-
3935
- /**
3936
- * Reassign File Hashes.
3937
- *
3938
- * The plugin calculates md5 hashes for all uploaded files, upon selection, to
3939
- * verify later if the files have changed or not. This function reassignes the
3940
- * hashes for all valid uploaded files. This function may take a lot of time
3941
- * depending on the number and size of the uploaded files.
3942
- *
3943
- * @since 2.4.1
3944
- *
3945
- * @global object $wpdb The Wordpress database object.
3946
- */
3947
- function wfu_reassign_hashes() {
3948
- global $wpdb;
3949
- $table_name1 = $wpdb->prefix . "wfu_log";
3950
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
3951
- if ( $plugin_options['hashfiles'] == '1' ) {
3952
- $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE filehash = \'\' AND date_to = 0');
3953
- foreach( $filerecs as $filerec ) {
3954
- //calculate full file path
3955
- $filepath = wfu_path_rel2abs($filerec->filepath);
3956
- if ( wfu_file_exists($filepath, "wfu_reassign_hashes") ) {
3957
- $filehash = wfu_md5_file($filepath, "wfu_reassign_hashes");
3958
- $wpdb->update($table_name1,
3959
- array( 'filehash' => $filehash ),
3960
- array( 'idlog' => $filerec->idlog ),
3961
- array( '%s' ),
3962
- array( '%d' )
3963
- );
3964
- }
3965
- }
3966
- }
3967
- }
3968
-
3969
- /**
3970
- * Make Uploaded File Database Record Obsolete.
3971
- *
3972
- * This function makes a database record of an uploaded file obsolete. This
3973
- * means that the file is considered not valid anymore. Any related thumbnails
3974
- * are deleted.
3975
- *
3976
- * @since 3.11.0
3977
- *
3978
- * @global object $wpdb The Wordpress database object.
3979
- *
3980
- * @redeclarable
3981
- *
3982
- * @param object $filerec The database record to make obsolete.
3983
- *
3984
- * @return bool|int Returns false if errors, or the number of rows affected if
3985
- * successful.
3986
- */
3987
- function wfu_make_rec_obsolete($filerec) {
3988
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3989
- global $wpdb;
3990
- $table_name1 = $wpdb->prefix . "wfu_log";
3991
- $filedata = wfu_get_filedata_from_rec($filerec, true);
3992
- //update db record accordingly
3993
- $wpdb->update($table_name1,
3994
- array( 'date_to' => date('Y-m-d H:i:s'), 'filedata' => wfu_encode_array_to_string($filedata) ),
3995
- array( 'idlog' => $filerec->idlog ),
3996
- array( '%s', '%s' ),
3997
- array( '%d' )
3998
- );
3999
- }
4000
-
4001
- /**
4002
- * Synchronize Plugin's Database.
4003
- *
4004
- * This function updates database to reflect the current status of files.
4005
- *
4006
- * @since 2.4.1
4007
- *
4008
- * @global object $wpdb The Wordpress database object.
4009
- *
4010
- * @redeclarable
4011
- *
4012
- * @return number The number of obsolete records found.
4013
- */
4014
- function wfu_sync_database() {
4015
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
4016
- global $wpdb;
4017
- $table_name1 = $wpdb->prefix . "wfu_log";
4018
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
4019
-
4020
- $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action <> \'other\' AND action <> \'datasubmit\' AND date_to = 0');
4021
- $obsolete_count = 0;
4022
- foreach( $filerecs as $filerec ) {
4023
- $obsolete = true;
4024
- //calculate full file path
4025
- $filepath = wfu_path_rel2abs($filerec->filepath);
4026
- if ( wfu_file_exists($filepath, "wfu_sync_database") ) {
4027
- if ( $plugin_options['hashfiles'] == '1' ) {
4028
- $filehash = wfu_md5_file($filepath, "wfu_sync_database");
4029
- if ( $filehash == $filerec->filehash ) $obsolete = false;
4030
- }
4031
- else {
4032
- $filesize = wfu_filesize($filepath, "wfu_sync_database");
4033
- if ( $filesize == $filerec->filesize ) $obsolete = false;
4034
- }
4035
- }
4036
- if ( $obsolete ) {
4037
- wfu_make_rec_obsolete($filerec);
4038
- $obsolete_count ++;
4039
- }
4040
- }
4041
- return $obsolete_count;
4042
- }
4043
-
4044
- /**
4045
- * Get Uploaded File Database Records of Specific User.
4046
- *
4047
- * This function is used the retrieve the files uploaded by a specific user by
4048
- * returning all the valid uploaded files' database records. If the user ID
4049
- * provided starts with 'guest' then this means that the user is a guest and
4050
- * retrieval will be done based on the session ID of the session that was
4051
- * generated between the user's browser and the website when the user uploaded
4052
- * files. This function will check if there are obsolete records. It will also
4053
- * return any additional user data.
4054
- *
4055
- * @since 3.0.0
4056
- *
4057
- * @global object $wpdb The Wordpress database object.
4058
- *
4059
- * @param int|string $userid The user ID. If the user is a guest, it must be a
4060
- * string starting with 'guest' and then including the session ID.
4061
- *
4062
- * @return array An array of user's database records of uploaded files.
4063
- */
4064
- function wfu_get_recs_of_user($userid) {
4065
- global $wpdb;
4066
- $table_name1 = $wpdb->prefix . "wfu_log";
4067
- $table_name2 = $wpdb->prefix . "wfu_userdata";
4068
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
4069
-
4070
- //if $userid starts with 'guest' then retrieval of records is done using sessionid and uploaduserid is zero (for guests)
4071
- if ( substr($userid, 0, 5) == 'guest' )
4072
- $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action <> \'other\' AND action <> \'datasubmit\' AND uploaduserid = 0 AND sessionid = \''.substr($userid, 5).'\' AND date_to = 0');
4073
- else
4074
- $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action <> \'other\' AND action <> \'datasubmit\' AND uploaduserid = '.$userid.' AND date_to = 0');
4075
- $out = array();
4076
- foreach( $filerecs as $filerec ) {
4077
- $obsolete = true;
4078
- //calculate full file path
4079
- $filepath = wfu_path_rel2abs($filerec->filepath);
4080
- if ( wfu_file_exists($filepath, "wfu_get_recs_of_user") ) {
4081
- if ( $plugin_options['hashfiles'] == '1' ) {
4082
- $filehash = wfu_md5_file($filepath, "wfu_get_recs_of_user");
4083
- if ( $filehash == $filerec->filehash ) $obsolete = false;
4084
- }
4085
- else {
4086
- $filesize = wfu_filesize($filepath, "wfu_get_recs_of_user");
4087
- if ( $filesize == $filerec->filesize ) $obsolete = false;
4088
- }
4089
- }
4090
- if ( $obsolete ) {
4091
- wfu_make_rec_obsolete($filerec);
4092
- }
4093
- else {
4094
- $filerec->userdata = null;
4095
- if ( $filerec->uploadid != '' )
4096
- $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
4097
- array_push($out, $filerec);
4098
- }
4099
- }
4100
-
4101
- return $out;
4102
- }
4103
-
4104
- /**
4105
- * Get Filtered Uploaded Files Database Records.
4106
- *
4107
- * This function gets a list of database records of uploaded files based on a
4108
- * list of filters. This function will check if there are obsolete records. It
4109
- * will also return any additional user data.
4110
- *
4111
- * @since 3.2.1
4112
- *
4113
- * @global object $wpdb The Wordpress database object.
4114
- *
4115
- * @redeclarable
4116
- *
4117
- * @param array $filter An array of filters to apply.
4118
- *
4119
- * @return array An array of matched database records of uploaded files.
4120
- */
4121
- function wfu_get_filtered_recs($filter) {
4122
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
4123
- global $wpdb;
4124
- $table_name1 = $wpdb->prefix . "wfu_log";
4125
- $table_name2 = $wpdb->prefix . "wfu_userdata";
4126
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
4127
-
4128
- $queries = array();
4129
- // add default filters
4130
- array_push($queries, 'a.action <> \'other\' AND a.action <> \'datasubmit\'');
4131
- array_push($queries, 'a.date_to = 0');
4132
- // construct user filter
4133
- if ( isset($filter['user']) ) {
4134
- if ( $filter['user']['all'] ) {
4135
- if ( $filter['user']['guests'] ) $query = 'a.uploaduserid >= 0';
4136
- else $query = 'a.uploaduserid > 0';
4137
- }
4138
- elseif ( count($filter['user']['ids']) == 1 && substr($filter['user']['ids'][0], 0, 5) == 'guest' )
4139
- $query = 'a.uploaduserid = 0 AND a.sessionid = \''.substr($filter['user']['ids'][0], 5).'\'';
4140
- else {
4141
- if ( $filter['user']['guests'] ) array_push($filter['user']['ids'], '0');
4142
- if ( count($filter['user']['ids']) == 1 ) $query = 'a.uploaduserid = '.$filter['user']['ids'][0];
4143
- else $query = 'a.uploaduserid in ('.implode(",",$filter['user']['ids']).')';
4144
- }
4145
- array_push($queries, $query);
4146
- }
4147
- // construct size filter
4148
- if ( isset($filter['size']) ) {
4149
- if ( isset($filter['size']['lower']) && isset($filter['size']['upper']) )
4150
- $query = 'a.filesize > '.$filter['size']['lower'].' AND a.filesize < '.$filter['size']['upper'];
4151
- elseif ( isset($filter['size']['lower']) ) $query = 'a.filesize > '.$filter['size']['lower'];
4152
- else $query = 'a.filesize < '.$filter['size']['upper'];
4153
- array_push($queries, $query);
4154
- }
4155
- // construct date filter
4156
- if ( isset($filter['date']) ) {
4157
- if ( isset($filter['date']['lower']) && isset($filter['date']['upper']) )
4158
- $query = 'a.uploadtime > '.$filter['date']['lower'].' AND a.uploadtime < '.$filter['date']['upper'];
4159
- elseif ( isset($filter['date']['lower']) ) $query = 'a.uploadtime > '.$filter['date']['lower'];
4160
- else $query = 'a.uploadtime < '.$filter['date']['upper'];
4161
- array_push($queries, $query);
4162
- }
4163
- // construct file pattern filter
4164
- if ( isset($filter['pattern']) ) {
4165
- $query = 'a.filepath REGEXP \''.wfu_upload_plugin_wildcard_to_mysqlregexp($filter['pattern']).'\'';
4166
- array_push($queries, $query);
4167
- }
4168
- // construct page/post filter
4169
- if ( isset($filter['post']) ) {
4170
- if ( count($filter['post']['ids']) == 1 ) $query = 'a.pageid = '.$filter['post']['ids'][0];
4171
- else $query = 'a.pageid in ('.implode(",",$filter['post']['ids']).')';
4172
- array_push($queries, $query);
4173
- }
4174
- // construct blog filter
4175
- if ( isset($filter['blog']) ) {
4176
- if ( count($filter['blog']['ids']) == 1 ) $query = 'a.blogid = '.$filter['blog']['ids'][0];
4177
- else $query = 'a.blogid in ('.implode(",",$filter['blog']['ids']).')';
4178
- array_push($queries, $query);
4179
- }
4180
- // construct userdata filter
4181
- if ( isset($filter['userdata']) ) {
4182
- if ( $filter['userdata']['criterion'] == "equal to" ) $valuecriterion = 'propvalue = \''.esc_sql($filter['userdata']['value']).'\'';
4183
- elseif ( $filter['userdata']['criterion'] == "starts with" ) $valuecriterion = 'propvalue LIKE \''.esc_sql($filter['userdata']['value']).'%\'';
4184
- elseif ( $filter['userdata']['criterion'] == "ends with" ) $valuecriterion = 'propvalue LIKE \'%'.esc_sql($filter['userdata']['value']).'\'';
4185
- elseif ( $filter['userdata']['criterion'] == "contains" ) $valuecriterion = 'propvalue LIKE \'%'.esc_sql($filter['userdata']['value']).'%\'';
4186
- elseif ( $filter['userdata']['criterion'] == "not equal to" ) $valuecriterion = 'propvalue <> \''.esc_sql($filter['userdata']['value']).'\'';
4187
- elseif ( $filter['userdata']['criterion'] == "does not start with" ) $valuecriterion = 'propvalue NOT LIKE \''.esc_sql($filter['userdata']['value']).'%\'';
4188
- elseif ( $filter['userdata']['criterion'] == "does not end with" ) $valuecriterion = 'propvalue NOT LIKE \'%'.esc_sql($filter['userdata']['value']).'\'';
4189
- elseif ( $filter['userdata']['criterion'] == "does not contain" ) $valuecriterion = 'propvalue NOT LIKE \'%'.esc_sql($filter['userdata']['value']).'%\'';
4190
- else $valuecriterion = 'propvalue = \''.esc_sql($filter['userdata']['value']).'\'';
4191
- $query = 'uploadid in (SELECT DISTINCT uploadid FROM '.$table_name2.' WHERE date_to = 0 AND property = \''.esc_sql($filter['userdata']['field']).'\' AND '.$valuecriterion.')';
4192
- array_push($queries, $query);
4193
- }
4194
-
4195
- /**
4196
- * Customize Filter Queries.
4197
- *
4198
- * This filter allows custom actions to midify the queries that will be used
4199
- * to filter the selected records of a file viewer.
4200
- *
4201
- * @since 4.6.2
4202
- *
4203
- * @param array $queries An array of queries to filter the selected records.
4204
- * @param array $filter The filter array that generated the queries.
4205
- */
4206
- $queries = apply_filters("_wfu_filtered_recs_queries", $queries, $filter);
4207
-
4208
- //Retrieval of uploaded file records is combined with retrieval of userdata
4209
- //records into one single database query using a left join. This technique,
4210
- //together with indexing of uploadid fields, results in dramatic speed up of
4211
- //returned results; all userdata of each uploaded file are encoded into a
4212
- //single field of the returned results called 'userdata_raw'. The function
4213
- //then parses userdata_raw and reconstructs the original userdata records.
4214
- $query = 'SELECT a.*, GROUP_CONCAT(CONCAT_WS("#", b.iduserdata, HEX(b.property), b.propkey, HEX(IFNULL(b.propvalue, "")), b.date_from) ORDER BY b.propkey ASC SEPARATOR "$") AS userdata_raw '.
4215
- 'FROM '.$table_name1.' a LEFT JOIN '.$table_name2.' b USING (uploadid) '.
4216
- 'WHERE '.implode(' AND ', $queries).' AND (b.date_to = 0 OR b.date_to IS NULL) GROUP BY a.idlog';
4217
- $filerecs = $wpdb->get_results($query);
4218
- $out = array();
4219
- foreach( $filerecs as $filerec ) {
4220
- $obsolete = true;
4221
- //calculate full file path
4222
- $filepath = wfu_path_rel2abs($filerec->filepath);
4223
- if ( wfu_file_exists($filepath, "wfu_get_filtered_recs") ) {
4224
- if ( $plugin_options['hashfiles'] == '1' ) {
4225
- $filehash = wfu_md5_file($filepath, "wfu_get_filtered_recs");
4226
- if ( $filehash == $filerec->filehash ) $obsolete = false;
4227
- }
4228
- else {
4229
- $filesize = wfu_filesize($filepath, "wfu_get_filtered_recs");
4230
- if ( $filesize == $filerec->filesize ) $obsolete = false;
4231
- }
4232
- }
4233
- if ( $obsolete ) {
4234
- wfu_make_rec_obsolete($filerec);
4235
- }
4236
- else {
4237
- $filerec->userdata = null;
4238
- if ( $filerec->uploadid != '' ) {
4239
- $filerec->userdata = array();
4240
- //the function parses userdata_raw field in order to reconstruct
4241
- //the original userdata records
4242
- $items = explode("$", $filerec->userdata_raw);
4243
- foreach ( $items as $item ) {
4244
- if ( trim($item) != "" ) {
4245
- $parts = explode("#", $item);
4246
- if ( count($parts) == 4 ) {
4247
- list($id, $label, $key, $value) = $parts;
4248
- $date_from = '0000-00-00 00:00:00';
4249
- }
4250
- else list($id, $label, $key, $value, $date_from) = $parts;
4251
- $userdata = new stdClass();
4252
- $userdata->iduserdata = $id;
4253
- $userdata->uploadid = $filerec->uploadid;
4254
- $userdata->property = wfu_plugin_decode_string($label);
4255
- $userdata->propkey = $key;
4256
- $userdata->propvalue = wfu_plugin_decode_string($value);
4257
- $userdata->date_from = $date_from;
4258
- $userdata->date_to = '0000-00-00 00:00:00';
4259
- array_push($filerec->userdata, $userdata);
4260
- }
4261
- }
4262
- if ( count($filerec->userdata) == 0 ) $filerec->userdata = null;
4263
- }
4264
- array_push($out, $filerec);
4265
- }
4266
- }
4267
-
4268
- return $out;
4269
- }
4270
-
4271
- /**
4272
- * Get Uncached Option.
4273
- *
4274
- * This function gets an option from the website's Options table. It will first
4275
- * delete any cached values of the option, so that the stored value in database
4276
- * is returned.
4277
- *
4278
- * @since 3.5.0
4279
- *
4280
- * @param string $option The option name to retrieve.
4281
- * @param mixed $default Optional. A default value to return in case option does
4282
- * not exist.
4283
- *
4284
- * @return mixed The uncached value of the option.
4285
- */
4286
- function wfu_get_uncached_option($option, $default = false) {
4287
- $GLOBALS['wp_object_cache']->delete( $option, 'options' );
4288
- return get_option($option, $default);
4289
- }
4290
-
4291
- /**
4292
- * Get Plugin Option.
4293
- *
4294
- * This function gets a plugin option from the website's Options table. It uses
4295
- * direct access to options table of the website in order to avoid caching
4296
- * problems that may happen when retrieving plugin options from parallel server-
4297
- * side scripts.
4298
- *
4299
- * @since 3.5.0
4300
- *
4301
- * @global object $wpdb The Wordpress database object.
4302
- *
4303
- * @param string $option The option name to retrieve.
4304
- * @param mixed $default A default value to return in case option does not
4305
- * exist.
4306
- * @param string $type Optional. The value type.
4307
- *
4308
- * @return mixed The value of the option.
4309
- */
4310
- function wfu_get_option($option, $default, $type = "array") {
4311
- global $wpdb;
4312
- $table_name1 = $wpdb->prefix . "options";
4313
- $val = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM $table_name1 WHERE option_name = %s", $option));
4314
- if ( $val === null && $default !== false ) $val = $default;
4315
- elseif ( $val !== null ) $val = ( $type == "array" ? wfu_decode_array_from_string($val) : $val );
4316
- return $val;
4317
- }
4318
-
4319
- /**
4320
- * Get Plugin Option Item.
4321
- *
4322
- * This function gets an option item from the website's Options table. Option
4323
- * items are stored in the option value in an encoded format like this:
4324
- *
4325
- * [item_name1]item_value1{item_name1}[item_name2]item_value2{item_name2}...
4326
- *
4327
- * This format can be parsed and get the value of a specific item using a single
4328
- * SQL command. This is exptremely important when working with parallel server-
4329
- * side scripts, otherwise data may be lost.
4330
- *
4331
- * @since 4.12.0
4332
- *
4333
- * @global object $wpdb The Wordpress database object.
4334
- *
4335
- * @param string $option The option name that contains the item.
4336
- * @param string $item The item name whose value to retrieve.
4337
- *
4338
- * @return null|string Null will be returned if option are item is not found,
4339
- * otherwise the item value will be returned as string.
4340
- */
4341
- function wfu_get_option_item($option, $item) {
4342
- global $wpdb;
4343
- $table_name1 = $wpdb->prefix . "options";
4344
- $val = $wpdb->get_var($wpdb->prepare("SELECT SQL_NO_CACHE IF (COUNT(option_value) = 0, NULL, IF (INSTR(option_value, %s) > 0, SUBSTRING_INDEX(SUBSTRING_INDEX(option_value, %s, -1), %s, 1), NULL)) FROM $table_name1 WHERE option_name = %s", '['.$item.']', '['.$item.']', '{'.$item.'}', $option));
4345
- //wfu_debug_log("read:".$item." value:".$val."\n");
4346
- return $val;
4347
- }
4348
-
4349
- /**
4350
- * Check If Plugin Option Item Exists.
4351
- *
4352
- * This function checks if an option item in the website's Options table exists.
4353
- * Option items and their format are described in wfu_get_option_item() function
4354
- * above.
4355
- *
4356
- * @since 4.12.0
4357
- *
4358
- * @global object $wpdb The Wordpress database object.
4359
- *
4360
- * @param string $option The option name that contains the item.
4361
- * @param string $item The item name whose existence to check.
4362
- *
4363
- * @return null|bool Null will be returned if option is not found, true if the
4364
- * item exists, false otherwise.
4365
- */
4366
- function wfu_option_item_exists($option, $item) {
4367
- global $wpdb;
4368
- $table_name1 = $wpdb->prefix . "options";
4369
- $exists = $wpdb->get_var($wpdb->prepare("SELECT SQL_NO_CACHE IF (COUNT(option_value) = 0, NULL, IF (INSTR(option_value, %s) > 0, TRUE, FALSE)) FROM $table_name1 WHERE option_name = %s", '['.$item.']', $option));
4370
- return $exists;
4371
- }
4372
-
4373
- /**
4374
- * Update Plugin Option.
4375
- *
4376
- * This function updates a plugin array option in the website's Options table or
4377
- * creates it if it does not exist. It makes direct access to the website's
4378
- * Options database table. It uses a single SQL command to insert or update the
4379
- * option. This is necessary when working with parallel server-side scripts,
4380
- * like the ones created when transferring multiple files to cloud services
4381
- * asynchronously. The common Wordpress functions get_option() and
4382
- * update_option() are not sufficient for such operations.
4383
- *
4384
- * @since 3.5.0
4385
- *
4386
- * @global object $wpdb The Wordpress database object.
4387
- *
4388
- * @param string $option The option name to update.
4389
- * @param mixed $value The new value of the option.
4390
- * @param string $type Optional. The value type.
4391
- */
4392
- function wfu_update_option($option, $value, $type = "array") {
4393
- global $wpdb;
4394
- $table_name1 = $wpdb->prefix . "options";
4395
- $value = ( $type == "array" ? wfu_encode_array_to_string($value) : $value );
4396
- $wpdb->query($wpdb->prepare("INSERT INTO $table_name1 (option_name, option_value) VALUES (%s, %s) ON DUPLICATE KEY UPDATE option_value = VALUES(option_value)", $option, $value));
4397
- }
4398
-
4399
- /**
4400
- * Run Process in Queue.
4401
- *
4402
- * It has been observed that parallel PHP scripts can read/write to the database
4403
- * and also the file system concurrently. This will cause problems with uploads.
4404
- * File parts are uploaded concurrently, however it is necessary that each one
4405
- * is processed at the server-side separately, before the next one starts. The
4406
- * reason is that when the server reads a new chunk, it stores and retrieves
4407
- * data from session. If more than one chunks write to session at the same time,
4408
- * then mixups will happen and the upload will eventually fail.
4409
- *
4410
- * This function put processes that need to run concurrently (called 'threads')
4411
- * in a FIFO queue based on a unique queue ID. The first thread that comes is
4412
- * the first to be executed. The next one will be executed after the first one
4413
- * finishes. A timeout loop checks the thread status. If a thread takes too long
4414
- * to complete, it is considered as failed and it is removed from the queue, so
4415
- * that the queue continues to the next threads.
4416
- *
4417
- * @since 4.12.0
4418
- *
4419
- * @param string $queue_id The unique queue ID.
4420
- * @param string $proc The function that is put in queue.
4421
- * @param array $params The function parameters.
4422
- *
4423
- * @return array {
4424
- * The result of queue execution.
4425
- *
4426
- * @type bool $result True if the process was executed successfully,
4427
- * false otherwise.
4428
- * @type string $thread_code The unique code of the current thread.
4429
- * @type integer $thread_index The index of the current thread.
4430
- * @type null|mixed $output The return value of the executed function in
4431
- * case of success, null otherwise.
4432
- * @type string $error Error code in case of thread execution failure.
4433
- * }
4434
- */
4435
- function wfu_run_process_in_queue($queue_id, $proc, $params) {
4436
- $ret = array(
4437
- "result" => false,
4438
- "thread_code" => "",
4439
- "thread_index" => 0,
4440
- "output" => null,
4441
- "error" => ""
4442
- );
4443
- if ( WFU_VAR("WFU_QUEUE_ACTIVE") == "true" ) {
4444
- $queue = "wfu_queue_".$queue_id;
4445
- if ( $queue_id == "" ) {
4446
- $ret["error"] = "noid";
4447
- return $ret;
4448
- }
4449
- $thread_code = wfu_create_random_string(16);
4450
- wfu_join_queue($queue_id, $thread_code);
4451
- $limit = intval(WFU_VAR("WFU_QUEUE_THREAD_TIMEOUT"));
4452
- $waitloop = intval(WFU_VAR("WFU_QUEUE_LOOP_DELAY")) * 1000;
4453
- $tcheck = time() + $limit;
4454
- $last_thread = "";
4455
- $abort = false;
4456
- while (true) {
4457
- $cur_thread = wfu_get_queue_thread($queue_id);
4458
- if ( $cur_thread == $thread_code ) break;
4459
- //calculate queue activity; if thread has changed then reset timer
4460
- if ( $cur_thread != $last_thread ) {
4461
- $last_thread = $cur_thread;
4462
- $tcheck = time() + $limit;
4463
- }
4464
- //if time limit has passed this means that the current queue thread
4465
- //is not progressing, so we need to exit the queue otherwise there
4466
- //will be an infinite loop
4467
- elseif ( time() > $tcheck ) {
4468
- wfu_remove_queue_thread($queue_id, $thread_code);
4469
- wfu_remove_queue_thread($queue_id, $cur_thread);
4470
- $abort = true;
4471
- break;
4472
- }
4473
- usleep($waitloop);
4474
- }
4475
- if ( $abort ) {
4476
- $ret["error"] = "abort_thread";
4477
- return $ret;
4478
- }
4479
- $thread_index = intval(wfu_get_option($queue."_count", 0, "string")) + 1;
4480
- wfu_update_option($queue."_count", $thread_index, "string");
4481
- }
4482
- //create an array of references to the function arguments and pass this to
4483
- //call_user_func_array instead of $args; this is a workaround to avoid PHP
4484
- //warnings when the original function passes arguments by reference
4485
- $args_byref = array();
4486
- foreach ( $params as $key => &$arg ) $args_byref[$key] = &$arg;
4487
- $output = call_user_func_array($proc, $args_byref);
4488
- $ret["result"] = true;
4489
- $ret["output"] = $output;
4490
- if ( WFU_VAR("WFU_QUEUE_ACTIVE") == "true" ) {
4491
- $ret["thread_code"] = $thread_code;
4492
- $ret["thread_index"] = $thread_index;
4493
- wfu_advance_queue($queue_id);
4494
- }
4495
- return $ret;
4496
- }
4497
-
4498
- /**
4499
- * Join Thread in Queue.
4500
- *
4501
- * This function adds a new thread in a queue. If the queue does not exist it
4502
- * will be created.
4503
- *
4504
- * @since 4.12.0
4505
- *
4506
- * @param string $queue_id The unique queue ID.
4507
- * @param string $thread The new thread code.
4508
- */
4509
- function wfu_join_queue($queue_id, $thread) {
4510
- global $wpdb;
4511
- if ( $queue_id == "" ) return;
4512
- $queue = "wfu_queue_".$queue_id;
4513
- $table_name1 = $wpdb->prefix . "options";
4514
- $wpdb->query($wpdb->prepare("INSERT INTO $table_name1 (option_name, option_value) VALUES (%s, %s) ON DUPLICATE KEY UPDATE option_value = CONCAT(option_value, IF (option_value = '', '', '|'), %s)", $queue, $thread, $thread));
4515
- }
4516
-
4517
- /**
4518
- * Advance Queue.
4519
- *
4520
- * This function advances a queue to the next thread.
4521
- *
4522
- * @since 4.12.0
4523
- *
4524
- * @param string $queue_id The unique queue ID.
4525
- */
4526
- function wfu_advance_queue($queue_id) {
4527
- global $wpdb;
4528
- if ( $queue_id == "" ) return;
4529
- $queue = "wfu_queue_".$queue_id;
4530
- $table_name1 = $wpdb->prefix . "options";
4531
- $wpdb->query($wpdb->prepare("UPDATE $table_name1 SET option_value = if (instr(option_value, '|') = 0, '', substr(option_value, instr(option_value, '|') + 1)) WHERE option_name = %s", $queue));
4532
- }
4533
-
4534
- /**
4535
- * Get Running Queue Thread.
4536
- *
4537
- * This function gets the currently running thread of a queue.
4538
- *
4539
- * @since 4.12.0
4540
- *
4541
- * @param string $queue_id The unique queue ID.
4542
- */
4543
- function wfu_get_queue_thread($queue_id) {
4544
- global $wpdb;
4545
- if ( $queue_id == "" ) return;
4546
- $queue = "wfu_queue_".$queue_id;
4547
- $table_name1 = $wpdb->prefix . "options";
4548
- return $wpdb->get_var($wpdb->prepare("SELECT substring_index(option_value, '|', 1) FROM $table_name1 WHERE option_name = %s", $queue));
4549
- }
4550
-
4551
- /**
4552
- * Remove Thread from Queue.
4553
- *
4554
- * This function removes a thread from a queue.
4555
- *
4556
- * @since 4.12.0
4557
- *
4558
- * @param string $queue_id The unique queue ID.
4559
- * @param string $thread The thread code to remove.
4560
- */
4561
- function wfu_remove_queue_thread($queue_id, $thread) {
4562
- global $wpdb;
4563
- if ( $queue_id == "" ) return;
4564
- $queue = "wfu_queue_".$queue_id;
4565
- $table_name1 = $wpdb->prefix . "options";
4566
- $wpdb->query($wpdb->prepare("UPDATE $table_name1 SET option_value = replace(replace(replace(replace(option_value, concat('|', %s, '|'), '|'), concat(%s, '|'), ''), concat('|', %s), ''), %s, '') WHERE option_name = %s", $thread, $thread, $thread, $thread, $queue));
4567
- }
4568
-
4569
- /**
4570
- * Remove Queue.
4571
- *
4572
- * This function removes a queue from options database table.
4573
- *
4574
- * @since 4.12.0
4575
- *
4576
- * @param string $queue_id The unique queue ID.
4577
- */
4578
- function wfu_remove_queue($queue_id) {
4579
- if ( $queue_id == "" ) return;
4580
- $queue = "wfu_queue_".$queue_id;
4581
- delete_option($queue);
4582
- }
4583
-
4584
- /**
4585
- * Update Plugin Option Item.
4586
- *
4587
- * This function updates an option item in the website's Options table. Option
4588
- * items and their format are described in wfu_get_option_item() function above.
4589
- * It has to be noted that the update of an option item requires a complex SQL
4590
- * query, consisting of an INSERT statement calling a SELECT statement. In case
4591
- * that many such queries are executed at the same time (like it happens when
4592
- * uploading a file in chunks), database deadlocks may occur. To overcome the
4593
- * situation, the transaction will be repeated until it succeeds or when a pre-
4594
- * defined timeout is reached.
4595
- *
4596
- * @since 4.12.0
4597
- *
4598
- * @global object $wpdb The Wordpress database object.
4599
- *
4600
- * @param string $option The option name that contains the item.
4601
- * @param string $item The item name whose value to retrieve.
4602
- * @param string $value The new value of the item.
4603
- *
4604
- * @return false|int False if there was a DB error, or the number of rows
4605
- * affected.
4606
- */
4607
- function wfu_update_option_item($option, $item, $value) {
4608
- global $wpdb;
4609
- $table_name1 = $wpdb->prefix . "options";
4610
- $timeout = time();
4611
- $val = false;
4612
- $suppress_wpdb_errors = $wpdb->suppress_errors;
4613
- if ( !$suppress_wpdb_errors ) $wpdb->suppress_errors(true);
4614
- while ( $val === false && time() < $timeout + intval(WFU_VAR("WFU_US_DEADLOCK_TIMEOUT")) ) {
4615
- $val = $wpdb->query($wpdb->prepare("INSERT INTO $table_name1 (option_name, option_value) SELECT SQL_NO_CACHE %s, IF (COUNT(option_value) = 0, %s, IF (INSTR(option_value, %s) = 0, CONCAT(option_value, %s), CONCAT(SUBSTRING_INDEX(option_value, %s, 1), %s, SUBSTRING_INDEX(option_value, %s, -1)))) FROM $table_name1 WHERE option_name = %s ON DUPLICATE KEY UPDATE option_value = VALUES(option_value)", $option, '['.$item.']'.$value.'{'.$item.'}', '['.$item.']', '['.$item.']'.$value.'{'.$item.'}', '['.$item.']', '['.$item.']'.$value.'{'.$item.'}', '{'.$item.'}', $option));
4616
- if ( $val === false && WFU_VAR("WFU_US_LOG_DBERRORS") == "true" ) error_log("Database error: ".$wpdb->last_error);
4617
- }
4618
- if ( !$suppress_wpdb_errors ) $wpdb->suppress_errors(false);
4619
- return $val;
4620
- }
4621
-
4622
- /**
4623
- * Delete Plugin Option.
4624
- *
4625
- * This function deletes a plugin array option from the website's Options table.
4626
- * It makes direct access to the website's Options database table so that
4627
- * caching problems are avoided, when used together with the previous
4628
- * wfu_get_option() and wfu_update_option() functions.
4629
- *
4630
- * @since 4.5.0
4631
- *
4632
- * @global object $wpdb The Wordpress database object.
4633
- *
4634
- * @param string $option The option name to update.
4635
- */
4636
- function wfu_delete_option($option) {
4637
- global $wpdb;
4638
- $table_name1 = $wpdb->prefix . "options";
4639
- $val = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM $table_name1 WHERE option_name = %s", $option));
4640
- $wpdb->query($wpdb->prepare("DELETE FROM $table_name1 WHERE option_name = %s", $option));
4641
- }
4642
-
4643
- /**
4644
- * Delete Plugin Option Item.
4645
- *
4646
- * This function deletes an option item in the website's Options table. Option
4647
- * items and their format are described in wfu_get_option_item() function above.
4648
- *
4649
- * @since 4.12.0
4650
- *
4651
- * @global object $wpdb The Wordpress database object.
4652
- *
4653
- * @param string $option The option name that contains the item.
4654
- * @param string $item The item name whose value to retrieve.
4655
- *
4656
- * @return false|int False if there was a DB error, or the number of rows
4657
- * affected.
4658
- */
4659
- function wfu_delete_option_item($option, $item) {
4660
- global $wpdb;
4661
- $table_name1 = $wpdb->prefix . "options";
4662
- $timeout = time();
4663
- $val = false;
4664
- $suppress_wpdb_errors = $wpdb->suppress_errors;
4665
- if ( !$suppress_wpdb_errors ) $wpdb->suppress_errors(true);
4666
- while ( $val === false && time() < $timeout + intval(WFU_VAR("WFU_US_DEADLOCK_TIMEOUT")) ) {
4667
- $val = $wpdb->query($wpdb->prepare("INSERT INTO $table_name1 (option_name, option_value) SELECT SQL_NO_CACHE %s, IF (COUNT(option_value) = 0, '', IF (INSTR(option_value, %s) = 0, option_value, CONCAT(SUBSTRING_INDEX(option_value, %s, 1), SUBSTRING_INDEX(option_value, %s, -1)))) FROM $table_name1 WHERE option_name = %s ON DUPLICATE KEY UPDATE option_value = VALUES(option_value)", $option, '['.$item.']', '['.$item.']', '{'.$item.'}', $option));
4668
- if ( $val === false && WFU_VAR("WFU_US_LOG_DBERRORS") == "true" ) error_log("Database error: ".$wpdb->last_error);
4669
- }
4670
- if ( !$suppress_wpdb_errors ) $wpdb->suppress_errors(false);
4671
- return $val;
4672
- }
4673
-
4674
- /**
4675
- * Prepare Data of Uploaded Files for Export.
4676
- *
4677
- * This function generates a file that contains data of uploaded files in csv
4678
- * format for export. It will either export data of all valid uploaded files or
4679
- * data of all uploaded files (valid or not) of a specififc user.
4680
- *
4681
- * @since 3.5.0
4682
- *
4683
- * @global object $wpdb The Wordpress database object.
4684
- *
4685
- * @redeclarable
4686
- *
4687
- * @param array $params An array of parameters to pass to the function.
4688
- *
4689
- * @return string The path of the file that contains the prepared data.
4690
- */
4691
- function wfu_export_uploaded_files($params) {
4692
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
4693
- global $wpdb;
4694
- $table_name1 = $wpdb->prefix . "wfu_log";
4695
- $table_name2 = $wpdb->prefix . "wfu_userdata";
4696
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
4697
- $sep = WFU_VAR("WFU_EXPORT_DATA_SEPARATOR");
4698
- $sep2 = WFU_VAR("WFU_EXPORT_USERDATA_SEPARATOR");
4699
- $includeall = isset($params["username"]);
4700
-
4701
- $contents = "";
4702
- $header = 'Name'.$sep.'Path'.$sep.'Upload User'.$sep.'Upload Time'.$sep.'Size'.$sep.'Page ID'.$sep.'Blog ID'.$sep.'Shortcode ID'.$sep.'Upload ID'.$sep.'User Data';
4703
- $contents = $header;
4704
- if ( $includeall ) {
4705
- $user = get_user_by('login', $params["username"]);
4706
- $userid = $user->ID;
4707
- $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE uploaduserid = '.$userid);
4708
- }
4709
- else $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action <> \'other\' AND date_to = 0');
4710
- foreach( $filerecs as $filerec ) {
4711
- if ( $filerec->action == 'datasubmit' ) $obsolete = false;
4712
- else {
4713
- $obsolete = true;
4714
- //calculate full file path
4715
- $filepath = wfu_path_rel2abs($filerec->filepath);
4716
- if ( wfu_file_exists($filepath, "wfu_export_uploaded_files") ) {
4717
- if ( $plugin_options['hashfiles'] == '1' ) {
4718
- $filehash = wfu_md5_file($filepath, "wfu_export_uploaded_files");
4719
- if ( $filehash == $filerec->filehash ) $obsolete = false;
4720
- }
4721
- else {
4722
- $filesize = wfu_filesize($filepath, "wfu_export_uploaded_files");
4723
- if ( $filesize == $filerec->filesize ) $obsolete = false;
4724
- }
4725
- }
4726
- }
4727
- //export file data if file is not obsolete
4728
- if ( !$obsolete || $includeall ) {
4729
- $filepath = wfu_hide_credentials_from_ftpurl($filerec->filepath);
4730
- $username = wfu_get_username_by_id($filerec->uploaduserid);
4731
- $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
4732
- $line = ( $filerec->action == 'datasubmit' ? 'datasubmit' : wfu_basename($filepath) );
4733
- $line .= $sep.( $filerec->action == 'datasubmit' ? '' : wfu_basedir($filepath) );
4734
- $line .= $sep.$username;
4735
- $line .= $sep.( $filerec->uploadtime == null ? "" : date("Y-m-d H:i:s", $filerec->uploadtime) );
4736
- $line .= $sep.( $filerec->action == 'datasubmit' ? '0' : $filerec->filesize );
4737
- $line .= $sep.( $filerec->pageid == null ? "" : $filerec->pageid );
4738
- $line .= $sep.( $filerec->blogid == null ? "" : $filerec->blogid );
4739
- $line .= $sep.( $filerec->sid == null ? "" : $filerec->sid );
4740
- $line .= $sep.$filerec->uploadid;
4741
- $line2 = "";
4742
- foreach ( $filerec->userdata as $userdata ) {
4743
- if ( $line2 != "" ) $line2 .= $sep2;
4744
- $line2 .= $userdata->property.":".str_replace(array("\n", "\r", "\r\n"), " ", $userdata->propvalue);
4745
- }
4746
- $line .= $sep.$line2;
4747
- $contents .= "\n".$line;
4748
- }
4749
- }
4750
- //create file
4751
- $path = tempnam(sys_get_temp_dir(), 'wfu');
4752
- file_put_contents($path, $contents);
4753
-
4754
- return $path;
4755
- }
4756
-
4757
- /**
4758
- * Get All Plugin Options.
4759
- *
4760
- * This function gets a list of all plugin's options and variables stored in
4761
- * user space (usually session).
4762
- *
4763
- * @since 4.9.1
4764
- *
4765
- * @return array {
4766
- * An array of all plugin options.
4767
- *
4768
- * $type string $name Name of option, an asterisk (*) denotes many
4769
- * occurencies.
4770
- * $type string $location Location of option, "db" or "session".
4771
- * $type bool $deleteOnPurge Delete this option when purging all plugin
4772
- * data.
4773
- * $type bool $extract Store this option when extracting plugin data.
4774
- * }
4775
- */
4776
- function wfu_get_all_plugin_options() {
4777
- //structure of $options array; every item has the following properties:
4778
- // 0: name of option, an asterisk (*) denotes many occurencies
4779
- // 1: location of option, "db" or "session"
4780
- // 2: delete this option when purging all plugin data
4781
- // 3: store this option when extracting plugin data
4782
- $options = array(
4783
- //stored plugin's Settings
4784
- array( "wordpress_file_upload_options", "db", true, true ),
4785
- //wfu_log table version
4786
- array( "wordpress_file_upload_table_log_version", "db", true, true ),
4787
- //wfu_userdata version
4788
- array( "wordpress_file_upload_table_userdata_version", "db", true, true ),
4789
- //wfu_dbxqueue version
4790
- array( "wordpress_file_upload_table_dbxqueue_version", "db", true, true ),
4791
- //stored hooks
4792
- array( "wordpress_file_upload_hooks", "db", true, true ),
4793
- //transfer manager properties
4794
- array( "wfu_transfermanager_props", "db", true, true ),
4795
- //last file record that was read
4796
- array( "wordpress_file_upload_last_idlog", "db", true, false ),
4797
- //indices of stored shortcode parameters
4798
- array( "wfu_params_index", "db", true, false ),
4799
- //stored shortcode parameters
4800
- array( "wfu_params_*", "db", true, false ),
4801
- //stored advanced environment variables
4802
- array( "wfu_environment_variables", "db", true, true ),
4803
- //stored global tokens
4804
- array( "wfu_gst_*", "db", true, false ),
4805
- //data of unfinished uploaded files
4806
- array( "wordpress_file_upload_unfinished_data", "db", true, false ),
4807
- //list of stored variables in dboption user state
4808
- array( "wfu_userstate_list", "db", true, false ),
4809
- //stored variable value in dboption user state
4810
- array( "wfu_userstate_*", "db", true, false ),
4811
- //last time dboption user state was checked
4812
- array( "wfu_userstate_list_last_check", "db", true, false ),
4813
- //stored personal data policies
4814
- array( "wordpress_file_upload_pd_policies", "db", true, true ),
4815
- //last time admin was notified about DOS attack
4816
- array( "wfu_admin_notification_about_DOS", "db", true, false ),
4817
- //stored token for adding uploader shortcode
4818
- array( "wfu_add_shortcode_ticket_for_wordpress_file_upload", "session", true, false ),
4819
- //stored token for adding file viewer shortcode
4820
- array( "wfu_add_shortcode_ticket_for_wordpress_file_upload_browser", "session", true, false ),
4821
- //session array holding dir and file paths
4822
- array( "wfu_filepath_safe_storage", "session", true, false ),
4823
- //stored rename file flag when renaming file
4824
- array( "wfu_rename_file", "session", true, false ),
4825
- //stored rename file error when renaming file
4826
- array( "wfu_rename_file_error", "session", true, false ),
4827
- //stored create dir flag when creating dir
4828
- array( "wfu_create_dir", "session", true, false ),
4829
- //stored create dir error when creating dir
4830
- array( "wfu_create_dir_error", "session", true, false ),
4831
- //stored file details error when updating file details
4832
- array( "wfu_filedetails_error", "session", true, false ),
4833
- //stored hook data key when updating a hook
4834
- array( "wfu_hook_data_key", "session", true, false ),
4835
- //stored hook data title when updating a hook
4836
- array( "wfu_hook_data_title", "session", true, false ),
4837
- //stored hook data description when updating a hook
4838
- array( "wfu_hook_data_description", "session", true, false ),
4839
- //stored hook data code when updating a hook
4840
- array( "wfu_hook_data_code", "session", true, false ),
4841
- //stored hook data status when updating a hook
4842
- array( "wfu_hook_data_status", "session", true, false ),
4843
- //stored hook data scope when updating a hook
4844
- array( "wfu_hook_data_scope", "session", true, false ),
4845
- //stored hook data error message when updating a hook
4846
- array( "wfu_hook_data_message", "session", true, false ),
4847
- //stored data of file transfers tab
4848
- array( "wfu_transfers_data", "session", true, false ),
4849
- //stored token of upload form
4850
- array( "wfu_token_*", "session", true, false ),
4851
- //stored data of uploaded files
4852
- array( "filedata_*", "session", true, false ),
4853
- //stored status of upload
4854
- array( "wfu_uploadstatus_*", "session", true, false ),
4855
- //flag determining if this is the first pass of an upload
4856
- array( "wfu_upload_first_pass_*", "session", true, false ),
4857
- //stored approved captcha verification code
4858
- array( "wfu_approvedcaptcha_*", "session", true, false ),
4859
- //stored short tokens
4860
- array( "wfu_ust_*", "session", true, false ),
4861
- //stored shortcode data
4862
- array( "wfu_shortcode_data_safe_storage", "session", true, false ),
4863
- //stored number of deleted thumbnails
4864
- array( "wfu_deleted_thumbnails_counter", "session", true, false ),
4865
- //stored number of added thumbnails
4866
- array( "wfu_added_thumbnails_counter", "session", true, false ),
4867
- //stored consent data
4868
- array( "WFU_Consent_Data", "session", true, false ),
4869
- //stored browser actions
4870
- array( "wfu_browser_actions_safe_storage", "session", true, false ),
4871
- //stored data of chunked uploads
4872
- array( "chunkdata_*", "session", true, false ),
4873
- //stored flag of uploader form refresh status
4874
- array( "wfu_check_refresh_*", "session", true, false ),
4875
- //stored upload start time
4876
- array( "wfu_start_time_*", "session", true, false ),
4877
- //stored upload start time
4878
- array( "wfu_start_time_*", "session", true, false )
4879
- );
4880
-
4881
-
4882
- return $options;
4883
- }
4884
-
4885
- //********************* Widget Functions ****************************************************************************************
4886
-
4887
- /**
4888
- * Get Plugin Widget Object From ID.
4889
- *
4890
- * This function gets the object instance of a plugin widget from its ID.
4891
- *
4892
- * @since 3.4.0
4893
- *
4894
- * @global array $wp_registered_widgets List of all registered widgets.
4895
- *
4896
- * @param string $widgetid The ID of the widget object instance.
4897
- *
4898
- * @return WP_Widget|false The widget object instance or false if not found.
4899
- */
4900
- function wfu_get_widget_obj_from_id($widgetid) {
4901
- global $wp_registered_widgets;
4902
-
4903
- if ( !isset($wp_registered_widgets[$widgetid]) ) return false;
4904
- if ( !isset($wp_registered_widgets[$widgetid]['callback']) ) return false;
4905
- if ( !isset($wp_registered_widgets[$widgetid]['callback'][0]) ) return false;
4906
- $obj = $wp_registered_widgets[$widgetid]['callback'][0];
4907
- if ( !($obj instanceof WP_Widget) ) return false;
4908
-
4909
- return $obj;
4910
- }
4911
-
4912
- //********************* Shortcode Options Functions ****************************************************************************************
4913
-
4914
- /**
4915
- * Adjust Shortcode Definitions For Multi-Occurrencies
4916
- *
4917
- * This function adjusts shortcode definitions so that more than one attribute
4918
- * definition exists for components who appear more than one time in placements
4919
- * attribute (like userdata).
4920
- *
4921
- * @since 3.3.0
4922
- *
4923
- * @param array $shortcode_atts The shortcode attributes.
4924
- *
4925
- * @return array The adjusted shortcode attributes.
4926
- */
4927
- function wfu_shortcode_attribute_definitions_adjusted($shortcode_atts) {
4928
- //get attribute definitions
4929
- $defs = wfu_attribute_definitions();
4930
- $defs_indexed = array();
4931
- $defs_indexed_flat = array();
4932
- foreach ( $defs as $def ) {
4933
- $defs_indexed[$def["attribute"]] = $def;
4934
- $defs_indexed_flat[$def["attribute"]] = $def["value"];
4935
- }
4936
- //get placement attribute from shortcode
4937
- $placements = "";
4938
- if ( isset($shortcode_atts["placements"]) ) $placements = $shortcode_atts["placements"];
4939
- else $placements = $defs_indexed_flat["placements"];
4940
- //get component definitions
4941
- $components = wfu_component_definitions();
4942
- //analyse components that can appear more than once in placements
4943
- foreach ( $components as $component ) {
4944
- if ( $component["multiplacements"] ) {
4945
- $componentid = $component["id"];
4946
- //count component occurrences in placements
4947
- $component_occurrences = substr_count($placements, $componentid);
4948
- if ( $component_occurrences > 1 && isset($defs_indexed[$componentid]) ) {
4949
- //add incremented attribute definitions in $defs_indexed_flat
4950
- //array if occurrences are more than one
4951
- for ( $i = 2; $i <= $component_occurrences; $i++ ) {
4952
- foreach ( $defs_indexed[$componentid]["dependencies"] as $attribute )
4953
- $defs_indexed_flat[$attribute.$i] = $defs_indexed_flat[$attribute];
4954
- }
4955
- }
4956
- }
4957
- }
4958
-
4959
- return $defs_indexed_flat;
4960
- }
4961
-
4962
- /**
4963
- * Generate Shortcode Parameters Index.
4964
- *
4965
- * This function generates a unique index number for each shortcode parameters.
4966
- * The function takes into account the current post ID, the shortcode ID and the
4967
- * current user's username to construct the index. All identifiers are stored in
4968
- * 'wfu_params_index' option. The index is used to store the shortcode
4969
- * attributes in options table for later use.
4970
- *
4971
- * @since 2.1.2
4972
- *
4973
- * @global object $post The current Post object.
4974
- *
4975
- * @param int $shortcode_id The ID of the shortcode.
4976
- * @param string $user_login The current user's username.
4977
- *
4978
- * @return string The index number of the shortcode parameters.
4979
- */
4980
- function wfu_generate_current_params_index($shortcode_id, $user_login) {
4981
- global $post;
4982
- $cur_index_str = '||'.$post->ID.'||'.$shortcode_id.'||'.$user_login;
4983
- $cur_index_str_search = '\|\|'.$post->ID.'\|\|'.$shortcode_id.'\|\|'.$user_login;
4984
- $index_str = get_option('wfu_params_index');
4985
- $index = explode("&&", $index_str);
4986
- foreach ($index as $key => $value) if ($value == "") unset($index[$key]);
4987
- $index_match = preg_grep("/".$cur_index_str_search."$/", $index);
4988
- if ( count($index_match) == 1 )
4989
- foreach ( $index_match as $key => $value )
4990
- if ( $value == "" ) unset($index_match[$key]);
4991
- if ( count($index_match) <= 0 ) {
4992
- $cur_index_rand = wfu_create_random_string(16);
4993
- array_push($index, $cur_index_rand.$cur_index_str);
4994
- }
4995
- else {
4996
- reset($index_match);
4997
- $cur_index_rand = substr(current($index_match), 0, 16);
4998
- if ( count($index_match) > 1 ) {
4999
- $index_match_keys = array_keys($index_match);
5000
- for ($i = 1; $i < count($index_match); $i++) {
5001
- $ii = $index_match_keys[$i];
5002
- unset($index[array_search($index_match[$ii], $index, true)]);
5003
- }
5004
- }
5005
- }
5006
- if ( count($index_match) != 1 ) {
5007
- $index_str = implode("&&", $index);
5008
- update_option('wfu_params_index', $index_str);
5009
- }
5010
- return $cur_index_rand;
5011
- }
5012
-
5013
- /**
5014
- * Get Stored Shortcode Parameters.
5015
- *
5016
- * This function gets the shortcode parameters, stored in options table, from
5017
- * its parameters index. Some times the index corresponds to 2 or more sets of
5018
- * params, so an additional check, based on session token needs to be done in
5019
- * order to find the correct one.
5020
- *
5021
- * @since 2.1.2
5022
- *
5023
- * @param string $params_index The parameters index.
5024
- * @param string $session_token Optional. A session token used to find the
5025
- * correct params.
5026
- *
5027
- * @return array {
5028
- * The shortcode parameters.
5029
- *
5030
- * $type string $unique_id The unique ID of the upload.
5031
- * $type int $page_id The ID of the page with the upload form.
5032
- * $type int $shortcode_id The ID of the shortcode.
5033
- * $type string $user_login The username of the user who made the
5034
- * upload.
5035
- * }
5036
- */
5037
- function wfu_get_params_fields_from_index($params_index, $session_token = "") {
5038
- $fields = array();
5039
- $index_str = get_option('wfu_params_index');
5040
- $index = explode("&&", $index_str);
5041
- $index_match = preg_grep("/^".$params_index."/", $index);
5042
- if ( count($index_match) >= 1 )
5043
- foreach ( $index_match as $key => $value )
5044
- if ( $value == "" ) unset($index_match[$key]);
5045
- if ( count($index_match) > 0 ) {
5046
- if ( $session_token == "" ) {
5047
- reset($index_match);
5048
- list($fields['unique_id'], $fields['page_id'], $fields['shortcode_id'], $fields['user_login']) = explode("||", current($index_match));
5049
- }
5050
- //some times $params_index corresponds to 2 or more sets of params, so
5051
- //we need to check session token in order to find the correct one
5052
- else {
5053
- $found = false;
5054
- foreach ( $index_match as $value ) {
5055
- list($fields['unique_id'], $fields['page_id'], $fields['shortcode_id'], $fields['user_login']) = explode("||", $value);
5056
- $sid = $fields['shortcode_id'];
5057
- if ( WFU_USVAR_exists("wfu_token_".$sid) && WFU_USVAR("wfu_token_".$sid) == $session_token ) {
5058
- $found = true;
5059
- break;
5060
- }
5061
- }
5062
- if ( !$found ) $fields = array();
5063
- }
5064
- }
5065
- return $fields;
5066
- }
5067
-
5068
- /**
5069
- * Store Shortcode Data in User's Space.
5070
- *
5071
- * This function stores shortcode data in current user's user space (usually
5072
- * session).
5073
- *
5074
- * @since 3.2.0
5075
- *
5076
- * @param array $data The shortcode data to store.
5077
- *
5078
- * @return string A unique code representing the stored data.
5079
- */
5080
- function wfu_safe_store_shortcode_data($data) {
5081
- $code = wfu_create_random_string(16);
5082
- $safe_storage = ( WFU_USVAR_exists('wfu_shortcode_data_safe_storage') ? WFU_USVAR('wfu_shortcode_data_safe_storage') : array() );
5083
- $safe_storage[$code] = $data;
5084
- WFU_USVAR_store('wfu_shortcode_data_safe_storage', $safe_storage);
5085
- return $code;
5086
- }
5087
-
5088
- /**
5089
- * Get Stored Shortcode Data from User's Space.
5090
- *
5091
- * This function gets stored shortcode data from current user's user space
5092
- * (usually session).
5093
- *
5094
- * @since 3.2.0
5095
- *
5096
- * @param string $code A unique code representing the stored data.
5097
- *
5098
- * @return array $data The stored shortcode data.
5099
- */
5100
- function wfu_get_shortcode_data_from_safe($code) {
5101
- //sanitize $code
5102
- $code = wfu_sanitize_code($code);
5103
- if ( $code == "" ) return '';
5104
- //return shortcode data from session variable, if exists
5105
- if ( !WFU_USVAR_exists('wfu_shortcode_data_safe_storage') ) return '';
5106
- $safe_storage = WFU_USVAR('wfu_shortcode_data_safe_storage');
5107
- if ( !isset($safe_storage[$code]) ) return '';
5108
- return $safe_storage[$code];
5109
- }
5110
-
5111
- /**
5112
- * Clear Stored Shortcode Data from User's Space.
5113
- *
5114
- * This function clears stored shortcode data from current user's user space
5115
- * (usually session).
5116
- *
5117
- * @since 3.2.0
5118
- *
5119
- * @param string $code A unique code representing the stored data.
5120
- */
5121
- function wfu_clear_shortcode_data_from_safe($code) {
5122
- //sanitize $code
5123
- $code = wfu_sanitize_code($code);
5124
- if ( $code == "" ) return;
5125
- //clear shortcode data from session variable, if exists
5126
- if ( !WFU_USVAR_exists('wfu_shortcode_data_safe_storage') ) return;
5127
- $safe_storage = WFU_USVAR('wfu_shortcode_data_safe_storage');
5128
- if ( !isset($safe_storage[$code]) ) return;
5129
- unset($safe_storage[$code]);
5130
- WFU_USVAR_store('wfu_shortcode_data_safe_storage', $safe_storage);
5131
- }
5132
-
5133
- /**
5134
- * Decode Dimensions Shortcode Attribute.
5135
- *
5136
- * This function converts shortcode attributes keeping dimensions data from
5137
- * string to array.
5138
- *
5139
- * @since 2.1.2
5140
- *
5141
- * @param string $dimensions_str The dimensions shortcode attribute.
5142
- *
5143
- * @return array An array of element dimension values.
5144
- */
5145
- function wfu_decode_dimensions($dimensions_str) {
5146
- $components = wfu_component_definitions();
5147
- $dimensions = array();
5148
-
5149
- foreach ( $components as $comp ) {
5150
- if ( $comp['dimensions'] == null ) $dimensions[$comp['id']] = "";
5151
- else foreach ( $comp['dimensions'] as $dimraw ) {
5152
- list($dim_id, $dim_name) = explode("/", $dimraw);
5153
- $dimensions[$dim_id] = "";
5154
- }
5155
- }
5156
- $dimensions_raw = explode(",", $dimensions_str);
5157
- foreach ( $dimensions_raw as $dimension_str ) {
5158
- $dimension_raw = explode(":", $dimension_str);
5159
- $item = strtolower(trim($dimension_raw[0]));
5160
- foreach ( array_keys($dimensions) as $key ) {
5161
- if ( $item == $key ) $dimensions[$key] = trim($dimension_raw[1]);
5162
- }
5163
- }
5164
- return $dimensions;
5165
- }
5166
-
5167
- /**
5168
- * Remove Item From Placements Attribute.
5169
- *
5170
- * This function correctly removes an item from placements attribute of the
5171
- * uploader shortcode.
5172
- *
5173
- * @since 3.8.0
5174
- *
5175
- * @param string $placements The placements shortcode attribute.
5176
- * @param string $item The item to remove.
5177
- *
5178
- * @return string The new placements attribute.
5179
- */
5180
- function wfu_placements_remove_item($placements, $item) {
5181
- $itemplaces = explode("/", $placements);
5182
- $newplacements = array();
5183
- foreach ( $itemplaces as $section ) {
5184
- $items_in_section = explode("+", trim($section));
5185
- $newsection = array();
5186
- foreach ( $items_in_section as $item_in_section ) {
5187
- $item_in_section = strtolower(trim($item_in_section));
5188
- if ( $item_in_section != "" && $item_in_section != $item ) array_push($newsection, $item_in_section);
5189
- }
5190
- if ( count($newsection) > 0 ) array_push($newplacements, implode("+", $newsection));
5191
- }
5192
- if ( count($newplacements) > 0 ) return implode("/", $newplacements);
5193
- else return "";
5194
- }
5195
-
5196
- //********************* Plugin Design Functions ********************************************************************************************
5197
-
5198
- /**
5199
- * Get Uploader Form Template.
5200
- *
5201
- * This function gets the template that will be used to render the uploader form
5202
- * of the plugin. If not template name is defined, the default template will be
5203
- * used.
5204
- *
5205
- * @since 4.0.0
5206
- *
5207
- * @redeclarable
5208
- *
5209
- * @param string $templatename The template to use.
5210
- *
5211
- * @return object The template object to use.
5212
- */
5213
- function wfu_get_uploader_template($templatename = "") {
5214
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5215
- if ($templatename != "") {
5216
- $classname = "WFU_UploaderTemplate_$templatename";
5217
- if ( class_exists($classname) )
5218
- return call_user_func(array($classname, 'get_instance'));
5219
- $filepath = ABSWPFILEUPLOAD_DIR."templates/uploader-$templatename.php";
5220
- if ( file_exists($filepath) ) {
5221
- include_once $filepath;
5222
- $classname = "WFU_UploaderTemplate_$templatename";
5223
- if ( class_exists($classname) )
5224
- return call_user_func(array($classname, 'get_instance'));
5225
- }
5226
- }
5227
- return WFU_Original_Template::get_instance();
5228
- }
5229
-
5230
- /**
5231
- * Get Front-End File Viewer Template.
5232
- *
5233
- * This function gets the template that will be used to render the front-end
5234
- * file viewer of the plugin. If not template name is defined, the default
5235
- * template will be used.
5236
- *
5237
- * @since 4.0.0
5238
- *
5239
- * @redeclarable
5240
- *
5241
- * @param string $templatename The template to use.
5242
- *
5243
- * @return object The template object to use.
5244
- */
5245
- function wfu_get_browser_template($templatename = "") {
5246
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5247
- if ($templatename != "") {
5248
- $classname = "WFU_BrowserTemplate_$templatename";
5249
- if ( class_exists($classname) )
5250
- return call_user_func(array($classname, 'get_instance'));
5251
- $filepath = ABSWPFILEUPLOAD_DIR."templates/browser-$templatename.php";
5252
- if ( file_exists($filepath) ) {
5253
- include_once $filepath;
5254
- $classname = "WFU_BrowserTemplate_$templatename";
5255
- if ( class_exists($classname) )
5256
- return call_user_func(array($classname, 'get_instance'));
5257
- }
5258
- }
5259
- return WFU_Original_Template::get_instance();
5260
- }
5261
-
5262
- /**
5263
- * Add Section in Uploader Form.
5264
- *
5265
- * This function adds a section in uploader form with the elements passed in
5266
- * parameters. The first parameter passed is an array of the shortcode
5267
- * attributes. The next parameters are the items to add in the new section.
5268
- *
5269
- * @since 2.1.2
5270
- *
5271
- * @redeclarable
5272
- *
5273
- * @return string The HTML code of the new section.
5274
- */
5275
- function wfu_add_div() {
5276
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5277
- $items_count = func_num_args();
5278
- if ( $items_count == 0 ) return "";
5279
- $items_raw = func_get_args();
5280
- $params = $items_raw[0];
5281
- unset($items_raw[0]);
5282
- $items = array( );
5283
- foreach ( $items_raw as $item_raw ) {
5284
- if ( is_array($item_raw) ) array_push($items, $item_raw);
5285
- }
5286
- $items_count = count($items);
5287
- if ( $items_count == 0 ) return "";
5288
-
5289
- $template = wfu_get_uploader_template($params["uploadertemplate"]);
5290
- $data["ID"] = $params["uploadid"];
5291
- $data["responsive"] = ( $params["fitmode"] == "responsive" );
5292
- $data["items"] = $items;
5293
- $data["params"] = $params;
5294
-
5295
- ob_start();
5296
- $template->wfu_row_container_template($data);
5297
- $str_output = ob_get_clean();
5298
- return $str_output;
5299
- }
5300
-
5301
- /**
5302
- * Generate Plugin Element Template Output.
5303
- *
5304
- * This function generates the output of a plugin's element based on the defined
5305
- * template and the data that the element will have.
5306
- *
5307
- * @since 4.0.0
5308
- *
5309
- * @param string $blockname The name of the element.
5310
- * @param array $data An array of data to pass to the element.
5311
- *
5312
- * @return array An array holding the output of element. The item 'css' of the
5313
- * array holds CSS code of the element. The item 'js' holds Javascript
5314
- * code of the element. Items 'line1', 'line2' and so on hold the lines
5315
- * of the HTML code of the element.
5316
- */
5317
- function wfu_read_template_output($blockname, $data) {
5318
- $output = array();
5319
- if ( isset($data["params"]["uploadertemplate"]) ) $template = wfu_get_uploader_template($data["params"]["uploadertemplate"]);
5320
- else $template = wfu_get_browser_template($data["params"]["browsertemplate"]);
5321
- $func = "wfu_".$blockname."_template";
5322
- $sid = $data["ID"];
5323
- ob_start();
5324
- call_user_func(array($template, $func), $data);
5325
- $str_output = ob_get_clean();
5326
-
5327
- $str_output = str_replace('$ID', $sid, $str_output);
5328
- //extract css, javascript and HTML from output
5329
- $match = array();
5330
- preg_match("/<style>(.*)<\/style>.*?<script.*?>(.*)<\/script>(.*)/s", $str_output, $match);
5331
- if ( count($match) == 4 ) {
5332
- $output["css"] = trim($match[1]);
5333
- $output["js"] = trim($match[2]);
5334
- $html = trim($match[3]);
5335
- $i = 1;
5336
- foreach( preg_split("/((\r?\n)|(\r\n?))/", $html) as $line )
5337
- $output["line".$i++] = $line;
5338
- }
5339
-
5340
- return $output;
5341
- }
5342
-
5343
- /**
5344
- * Generate Plugin Element Output.
5345
- *
5346
- * This function generates the final HTML code of a plugin's element that is
5347
- * ready for output.
5348
- *
5349
- * @since 4.0.0
5350
- *
5351
- * @param string $blockname The name of the element.
5352
- * @param array $params The shortcode attributes.
5353
- * @param array $additional_params Additional parameters passed to the function
5354
- * specific to the element.
5355
- * @param int $occurrence_index The occurrence index of the element, in case
5356
- * that placements attribute contains more than one occurrencies of this
5357
- * element.
5358
- *
5359
- * @return string The HTML code of the element.
5360
- */
5361
- function wfu_template_to_HTML($blockname, $params, $additional_params, $occurrence_index) {
5362
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
5363
- $block = call_user_func("wfu_prepare_".$blockname."_block", $params, $additional_params, $occurrence_index);
5364
- if ( isset($params["uploadid"]) ) {
5365
- $ID = $params["uploadid"];
5366
- $WF = "WFU";
5367
- }
5368
- else {
5369
- $ID = $params["browserid"];
5370
- $WF = "WFUB";
5371
- }
5372
- $css = $block["css"];
5373
- if ( $block["js"] != "" ) {
5374
- $js = 'var '.$WF.'_JS_'.$ID.'_'.$blockname.' = function() {';
5375
- $js .= "\n".$block["js"];
5376
- $js .= "\n".'}';
5377
- $js .= "\n".'wfu_run_js("window", "'.$WF.'_JS_'.$ID.'_'.$blockname.'");';
5378
- }
5379
- //relax css rules if this option is enabled
5380
- if ( $plugin_options['relaxcss'] == '1' ) $css = preg_replace('#.*?/\*relax\*/\s*#', '', $css);
5381
- $echo_str = wfu_css_to_HTML($css);
5382
- $echo_str .= "\n".wfu_js_to_HTML($js);
5383
- $k = 1;
5384
- while ( isset($block["line".$k]) ) {
5385
- if ( $block["line".$k] != "" ) $echo_str .= "\n".$block["line".$k];
5386
- $k++;
5387
- }
5388
-
5389
- return $echo_str;
5390
- }
5391
-
5392
- /**
5393
- * Extract CSS and Javascript Code From Components.
5394
- *
5395
- * This function extracts CSS and Javascript code from a components array
5396
- * holding its output.
5397
- *
5398
- * @since 4.0.0
5399
- *
5400
- * @param array $section_array The component output to analyse.
5401
- * @param string $css The parameter to store extracted CSS code.
5402
- * @param string $js The parameter to store extracted Javascript code.
5403
- */
5404
- function wfu_extract_css_js_from_components($section_array, &$css, &$js) {
5405
- for ( $i = 1; $i < count($section_array); $i++ ) {
5406
- if ( isset($section_array[$i]["css"]) ) $css .= ( $css == "" ? "" : "\n" ).$section_array[$i]["css"];
5407
- if ( isset($section_array[$i]["js"]) ) $js .= ( $js == "" ? "" : "\n" ).$section_array[$i]["js"];
5408
- }
5409
- return;
5410
- }
5411
-
5412
- /**
5413
- * Add Loading Overlay in Plugin's Form.
5414
- *
5415
- * This function adds an overlay onto a plugin's form (uploader form or file
5416
- * viewer) that shows a 'loading' icon when necessary.
5417
- *
5418
- * @since 3.5.0
5419
- *
5420
- * @redeclarable
5421
- *
5422
- * @param string $dlp Tab prefix of each HTML line.
5423
- * @param string $code A code string to uniquely identify the overlay.
5424
- *
5425
- * @return string The HTML code of the loading overlay.
5426
- */
5427
- function wfu_add_loading_overlay($dlp, $code) {
5428
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5429
- $echo_str = $dlp.'<div id="wfu_'.$code.'_overlay" style="margin:0; padding: 0; width:100%; height:100%; position:absolute; left:0; top:0; border:none; background:none; display:none;">';
5430
- $echo_str .= $dlp."\t".'<div style="margin:0; padding: 0; width:100%; height:100%; position:absolute; left:0; top:0; border:none; background-color:rgba(255,255,255,0.8); z-index:1;""></div>';
5431
- $echo_str .= $dlp."\t".'<table style="margin:0; padding: 0; table-layout:fixed; width:100%; height:100%; position:absolute; left:0; top:0; border:none; background:none; z-index:2;"><tbody><tr><td align="center" style="border:none;">';
5432
- $echo_str .= $dlp."\t\t".'<img src="'.WFU_IMAGE_OVERLAY_LOADING.'" /><br /><span>loading...</span>';
5433
- $echo_str .= $dlp."\t".'</td></tr></tbody></table>';
5434
- $echo_str .= $dlp.'</div>';
5435
-
5436
- return $echo_str;
5437
- }
5438
-
5439
- /**
5440
- * Add Pagination Header in Plugin's Form.
5441
- *
5442
- * This function adds a pagination header onto a plugin's form (uploader form or
5443
- * file viewer).
5444
- *
5445
- * @since 3.5.0
5446
- *
5447
- * @redeclarable
5448
- *
5449
- * @param string $dlp Tab prefix of each HTML line.
5450
- * @param string $code A code string to uniquely identify the pagination header.
5451
- * @param int $curpage The current page to show in the pagination header.
5452
- * @param int $pages Number of pages of the pagination header.
5453
- * @param bool $nonce Optional. If false then a nonce will also be created.
5454
- *
5455
- * @return string The HTML code of the pagination header.
5456
- */
5457
- function wfu_add_pagination_header($dlp, $code, $curpage, $pages, $nonce = false) {
5458
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5459
- if ($nonce === false) $nonce = wp_create_nonce( 'wfu-'.$code.'-page' );
5460
- $echo_str = $dlp.'<div style="float:right;">';
5461
- $echo_str .= $dlp."\t".'<label id="wfu_'.$code.'_first_disabled" style="margin:0 4px; font-weight:bold; opacity:0.5; cursor:default; display:'.( $curpage == 1 ? 'inline' : 'none' ).';">&#60;&#60;</label>';
5462
- $echo_str .= $dlp."\t".'<label id="wfu_'.$code.'_prev_disabled" style="margin:0 4px; font-weight:bold; opacity:0.5; cursor:default; display:'.( $curpage == 1 ? 'inline' : 'none' ).';">&#60;</label>';
5463
- $echo_str .= $dlp."\t".'<a id="wfu_'.$code.'_first" href="javascript:wfu_goto_'.$code.'_page(\''.$nonce.'\', \'first\');" style="margin:0 4px; font-weight:bold; display:'.( $curpage == 1 ? 'none' : 'inline' ).';">&#60;&#60;</a>';
5464
- $echo_str .= $dlp."\t".'<a id="wfu_'.$code.'_prev" href="javascript:wfu_goto_'.$code.'_page(\''.$nonce.'\', \'prev\');" style="margin:0 4px; font-weight:bold; display:'.( $curpage == 1 ? 'none' : 'inline' ).';">&#60;</a>';
5465
- $echo_str .= $dlp."\t".'<label style="margin:0 0 0 4px; cursor:default;">'.WFU_PAGINATION_PAGE.'</label>';
5466
- $echo_str .= $dlp."\t".'<select id="wfu_'.$code.'_pages" style="margin:0 4px;" onchange="wfu_goto_'.$code.'_page(\''.$nonce.'\', \'sel\');">';
5467
- for ( $i = 1; $i <= $pages; $i++ )
5468
- $echo_str .= $dlp."\t\t".'<option value="'.$i.'"'.( $i == $curpage ? ' selected="selected"' : '' ).'>'.$i.'</option>';
5469
- $echo_str .= $dlp."\t".'</select>';
5470
- $echo_str .= $dlp."\t".'<label style="margin:0 4px 0 0; cursor:default;">'.WFU_PAGINATION_OF.$pages.'</label>';
5471
- $echo_str .= $dlp."\t".'<label id="wfu_'.$code.'_next_disabled" style="margin:0 4px; font-weight:bold; opacity:0.5; cursor:default; display:'.( $curpage == $pages ? 'inline' : 'none' ).';">&#62;</label>';
5472
- $echo_str .= $dlp."\t".'<label id="wfu_'.$code.'_last_disabled" style="margin:0 4px; font-weight:bold; opacity:0.5; cursor:default; display:'.( $curpage == $pages ? 'inline' : 'none' ).';">&#62;&#62;</label>';
5473
- $echo_str .= $dlp."\t".'<a id="wfu_'.$code.'_next" href="javascript:wfu_goto_'.$code.'_page(\''.$nonce.'\', \'next\');" style="margin:0 4px; font-weight:bold; display:'.( $curpage == $pages ? 'none' : 'inline' ).';">&#62;</a>';
5474
- $echo_str .= $dlp."\t".'<a id="wfu_'.$code.'_last" href="javascript:wfu_goto_'.$code.'_page(\''.$nonce.'\', \'last\');" style="margin:0 4px; font-weight:bold; display:'.( $curpage == $pages ? 'none' : 'inline' ).';">&#62;&#62;</a>';
5475
- $echo_str .= $dlp.'</div>';
5476
-
5477
- return $echo_str;
5478
- }
5479
-
5480
- /**
5481
- * Add Bulk Actions Header in Plugin's Form.
5482
- *
5483
- * This function adds a bulk actions header onto a plugin's form (file viewer).
5484
- *
5485
- * @since 3.8.5
5486
- *
5487
- * @redeclarable
5488
- *
5489
- * @param string $dlp Tab prefix of each HTML line.
5490
- * @param string $code A code string to uniquely identify the bulk actions
5491
- * header.
5492
- * @param array $actions {
5493
- * The list of actions of the bulk actions header.
5494
- *
5495
- * $type string $name The name slug of the action.
5496
- * $type string $title The title of the action.
5497
- * }
5498
- *
5499
- * @return string The HTML code of the bulk actions header.
5500
- */
5501
- function wfu_add_bulkactions_header($dlp, $code, $actions) {
5502
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5503
- $echo_str = $dlp.'<div style="float:left;">';
5504
- $echo_str .= $dlp."\t".'<select id="wfu_'.$code.'_bulkactions" onchange="wfu_apply_bulkaction_select(\''.$code.'\');">';
5505
- $echo_str .= $dlp."\t\t".'<option value="" selected="selected">'.( substr($code, 0, 8) == "browser_" ? WFU_BROWSER_BULKACTION_TITLE : "Bulk Actions").'</option>';
5506
- foreach ( $actions as $action )
5507
- $echo_str .= $dlp."\t\t".'<option value="'.$action["name"].'">'.$action["title"].'</option>';
5508
- $echo_str .= $dlp."\t".'</select>';
5509
- $echo_str .= $dlp."\t".'<input type="button" class="button action" value="'.( substr($code, 0, 8) == "browser_" ? WFU_BROWSER_BULKACTION_LABEL : "Apply").'" onclick="wfu_apply_'.$code.'_bulkaction();" />';
5510
- $echo_str .= $dlp."\t".'<img src="'.WFU_IMAGE_OVERLAY_LOADING.'" style="display:none;" />';
5511
- $echo_str .= $dlp.'</div>';
5512
-
5513
- return $echo_str;
5514
- }
5515
-
5516
- /**
5517
- * Parse Colors From Color Template.
5518
- *
5519
- * This function converts a color template (color triplet) into an array of
5520
- * color values.
5521
- *
5522
- * @since 2.1.2
5523
- *
5524
- * @param string $template A color template to parse.
5525
- *
5526
- * @return array {
5527
- * A triplet of color values.
5528
- *
5529
- * $type string $color Text color value.
5530
- * $type string $bgcolor Background color value.
5531
- * $type string $borcolor Border color value.
5532
- * }
5533
- */
5534
- function wfu_prepare_message_colors($template) {
5535
- $color_array = explode(",", $template);
5536
- $colors['color'] = $color_array[0];
5537
- $colors['bgcolor'] = $color_array[1];
5538
- $colors['borcolor'] = $color_array[2];
5539
- return $colors;
5540
- }
5541
-
5542
- //********************* Email Functions ****************************************************************************************************
5543
-
5544
- /**
5545
- * Send Notification Email.
5546
- *
5547
- * This function sends a notification email after files have been uploaded.
5548
- *
5549
- * @since 2.1.2
5550
- *
5551
- * @global object $blog_id The ID of the current blog.
5552
- *
5553
- * @redeclarable
5554
- *
5555
- * @param object $user The user that uploaded the files.
5556
- * @param array $uploaded_file_paths An array of full paths of the uploaded
5557
- * files.
5558
- * @param array $userdata_fields An array of userdata fields, if any.
5559
- * @param array $params The shortcode attributes.
5560
- *
5561
- * @return string Empty if operation was successful, an error message otherwise.
5562
- */
5563
- function wfu_send_notification_email($user, $uploaded_file_paths, $userdata_fields, $params) {
5564
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5565
- global $blog_id;
5566
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
5567
-
5568
- //get consent status
5569
- $consent_revoked = ( $plugin_options["personaldata"] == "1" && $params["consent_result"] == "0" );
5570
- $not_store_files = ( $params["personaldatatypes"] == "userdata and files" );
5571
- //create necessary variables
5572
- $only_filename_list = "";
5573
- $target_path_list = "";
5574
- foreach ( $uploaded_file_paths as $filepath ) {
5575
- $only_filename_list .= ( $only_filename_list == "" ? "" : ", " ).wfu_basename($filepath);
5576
- $target_path_list .= ( $target_path_list == "" ? "" : ", " ).$filepath;
5577
- }
5578
-
5579
- //apply wfu_before_email_notification filter
5580
- $changable_data['recipients'] = $params["notifyrecipients"];
5581
- $changable_data['subject'] = $params["notifysubject"];
5582
- $changable_data['message'] = $params["notifymessage"];
5583
- $changable_data['headers'] = $params["notifyheaders"];
5584
- $changable_data['user_data'] = $userdata_fields;
5585
- $changable_data['filename'] = $only_filename_list;
5586
- $changable_data['filepath'] = $target_path_list;
5587
- $changable_data['error_message'] = '';
5588
- $additional_data['shortcode_id'] = $params["uploadid"];
5589
- /**
5590
- * Customize Notification Email.
5591
- *
5592
- * This filter allows custom actions to modify the notification email
5593
- * that is sent after a file upload.
5594
- *
5595
- * @since 2.7.3
5596
- *
5597
- * @param array $changable_data {
5598
- * Email parameters that can be changed.
5599
- *
5600
- * @type string $recipients A comma-separated list of email recipients.
5601
- * @type string $subject The email subject.
5602
- * @type string $message The email body.
5603
- * @type array $user_data Additional user data associated with the
5604
- * uploaded files.
5605
- * @type string $filename A comma-separated list of file names.
5606
- * @type string $filepath A comma-separated list of file full paths.
5607
- * @type string $error_message An error message that needs to be
5608
- * populated in case the email must not be sent.
5609
- * }
5610
- * @param array $additional_data {
5611
- * Additional parameters of the upload.
5612
- *
5613
- * @type int $shortcode_id The plugin ID of the upload form.
5614
- * }
5615
- */
5616
- $ret_data = apply_filters('wfu_before_email_notification', $changable_data, $additional_data);
5617
-
5618
- if ( $ret_data['error_message'] == '' ) {
5619
- $notifyrecipients = $ret_data['recipients'];
5620
- $notifysubject = $ret_data['subject'];
5621
- $notifymessage = $ret_data['message'];
5622
- $notifyheaders = $ret_data['headers'];
5623
- $userdata_fields = $ret_data['user_data'];
5624
- $only_filename_list = $ret_data['filename'];
5625
- $target_path_list = $ret_data['filepath'];
5626
-
5627
- if ( 0 == $user->ID ) {
5628
- $user_login = "guest";
5629
- $user_email = "";
5630
- }
5631
- else {
5632
- $user_login = $user->user_login;
5633
- $user_email = $user->user_email;
5634
- }
5635
- $search = array ('/%useremail%/', '/%n%/', '/%dq%/', '/%brl%/', '/%brr%/');
5636
- $replace = array ($user_email, "\n", "\"", "[", "]");
5637
- foreach ( $userdata_fields as $userdata_key => $userdata_field ) {
5638
- $ind = 1 + $userdata_key;
5639
- array_push($search, '/%userdata'.$ind.'%/');
5640
- array_push($replace, $userdata_field["value"]);
5641
- }
5642
- // $notifyrecipients = trim(preg_replace('/%useremail%/', $user_email, $params["notifyrecipients"]));
5643
- $notifyrecipients = preg_replace($search, $replace, $notifyrecipients);
5644
- $search = array ('/%n%/', '/%dq%/', '/%brl%/', '/%brr%/');
5645
- $replace = array ("\n", "\"", "[", "]");
5646
- $notifyheaders = preg_replace($search, $replace, $notifyheaders);
5647
- $search = array ('/%username%/', '/%useremail%/', '/%filename%/', '/%filepath%/', '/%blogid%/', '/%pageid%/', '/%pagetitle%/', '/%n%/', '/%dq%/', '/%brl%/', '/%brr%/');
5648
- $replace = array ($user_login, ( $user_email == "" ? "no email" : $user_email ), $only_filename_list, $target_path_list, $blog_id, $params["pageid"], get_the_title($params["pageid"]), "\n", "\"", "[", "]");
5649
- foreach ( $userdata_fields as $userdata_key => $userdata_field ) {
5650
- $ind = 1 + $userdata_key;
5651
- array_push($search, '/%userdata'.$ind.'%/');
5652
- array_push($replace, $userdata_field["value"]);
5653
- }
5654
- $notifysubject = preg_replace($search, $replace, $notifysubject);
5655
- $notifymessage = preg_replace($search, $replace, $notifymessage);
5656
-
5657
- if ( $params["attachfile"] == "true" ) {
5658
- $notify_sent = wp_mail($notifyrecipients, $notifysubject, $notifymessage, $notifyheaders, $uploaded_file_paths);
5659
- }
5660
- else {
5661
- $notify_sent = wp_mail($notifyrecipients, $notifysubject, $notifymessage, $notifyheaders);
5662
- }
5663
- //delete files if it is required by consent policy
5664
- if ( $consent_revoked && $not_store_files ) {
5665
- foreach ( $uploaded_file_paths as $file ) wfu_unlink($file, "wfu_send_notification_email");
5666
- }
5667
- return ( $notify_sent ? "" : WFU_WARNING_NOTIFY_NOTSENT_UNKNOWNERROR );
5668
- }
5669
- else return $ret_data['error_message'];
5670
- }
5671
-
5672
- /**
5673
- * Send Notification Email to Admin.
5674
- *
5675
- * This function sends a notification email to admin.
5676
- *
5677
- * @since 3.9.0
5678
- *
5679
- * @redeclarable
5680
- *
5681
- * @param string $subject The email subject.
5682
- * @param string $message The emal message.
5683
- */
5684
- function wfu_notify_admin($subject, $message) {
5685
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5686
- $admin_email = get_option("admin_email");
5687
- if ( $admin_email === false ) return;
5688
- wp_mail($admin_email, $subject, $message);
5689
- }
5690
-
5691
- //********************* Media Functions ****************************************************************************************************
5692
-
5693
- /**
5694
- * Create Media Attachment of Uploaded File.
5695
- *
5696
- * This function creates a media attachment and associates it with an uploaded
5697
- * file.
5698
- *
5699
- * This function incorporates contributions from Aaron Olin who made some
5700
- * corrections regarding the upload path.
5701
- *
5702
- * @since 2.2.1
5703
- *
5704
- * @redeclarable
5705
- *
5706
- * @param string $file_path The file path of the uploaded file.
5707
- * @param array $userdata_fields Any userdata fields defined with the file.
5708
- * @param int $page_id The ID of a page to link the attachment.
5709
- *
5710
- * @return int The ID of the created Media attachment.
5711
- */
5712
- function wfu_process_media_insert($file_path, $userdata_fields, $page_id){
5713
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5714
- $wp_upload_dir = wp_upload_dir();
5715
- $filetype = wp_check_filetype( wfu_basename( $file_path ), null );
5716
-
5717
- $attachment = array(
5718
- 'guid' => $wp_upload_dir['url'] . '/' . wfu_basename( $file_path ),
5719
- 'post_mime_type' => $filetype['type'],
5720
- 'post_title' => preg_replace( '/\.[^.]+$/', '', wfu_basename( $file_path ) ),
5721
- 'post_content' => '',
5722
- 'post_status' => 'inherit'
5723
- );
5724
-
5725
- $attach_id = wp_insert_attachment( $attachment, $file_path, $page_id );
5726
-
5727
- // If file is an image, process the default thumbnails for previews
5728
- require_once(ABSPATH . 'wp-admin/includes/image.php');
5729
- $attach_data = wp_generate_attachment_metadata( $attach_id, $file_path );
5730
- // Add userdata as attachment metadata
5731
- foreach ( $userdata_fields as $userdata_field )
5732
- $attach_data["WFU User Data"][$userdata_field["label"]] = $userdata_field["value"];
5733
- $update_attach = wp_update_attachment_metadata( $attach_id, $attach_data );
5734
- // link attachment with file in plugin's database
5735
- $filedata = wfu_get_filedata($file_path, true);
5736
- if ( $filedata != null ) {
5737
- $filedata["media"] = array(
5738
- "type" => "data",
5739
- "attach_id" => $attach_id
5740
- );
5741
- wfu_save_filedata_from_id($filedata["general"]["idlog"], $filedata);
5742
- }
5743
-
5744
- return $attach_id;
5745
- }
5746
-
5747
- /**
5748
- * Check If File Extension is Common Image.
5749
- *
5750
- * This function checks whether a file extension is a common image.
5751
- *
5752
- * @since 4.13.1
5753
- *
5754
- * @redeclarable
5755
- *
5756
- * @param string $ext The file extension to check.
5757
- *
5758
- * @return bool True if the extension is image, false otherwise.
5759
- */
5760
- function wfu_file_extension_is_common_image($ext) {
5761
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5762
- //define valid image types
5763
- $images = array( "jpeg", "jpg", "jpe", "pjpeg", "gif", "png", "tif", "bmp" );
5764
- return in_array($ext, $images);
5765
- }
5766
-
5767
- //********************* Form Fields Functions ****************************************************************************************************
5768
-
5769
- /**
5770
- * Parse Userdata Callback.
5771
- *
5772
- * This is a callback function used in userdata parsing.
5773
- *
5774
- * @since 3.3.1
5775
- *
5776
- * @param string $matches A preg_replace_callback() function match.
5777
- *
5778
- * @return string The processed $matches string.
5779
- */
5780
- function wfu_preg_replace_callback_func($matches) {
5781
- return str_replace("[/]", "/", $matches[0]);
5782
- }
5783
-
5784
- /**
5785
- * Parse Upload Form Userdata.
5786
- *
5787
- * This function parses userdatalabel attribute, which holds userdata fields
5788
- * properties, into an array.
5789
- *
5790
- * @since 3.3.0
5791
- *
5792
- * @param string $value Upload form userdatalabel attribute.
5793
- *
5794
- * @return array {
5795
- * Parsed userdata fields properties.
5796
- *
5797
- * $type array {
5798
- * Parsed userdata field properties.
5799
- *
5800
- * $type string $type The type of the field.
5801
- * $type string $label The label of the field.
5802
- * $type string $labelposition The position of the label in
5803
- * relation to the field.
5804
- * $type bool $required Field is required.
5805
- * $type bool $donotautocomplete Field must not be autocompleted.
5806
- * $type bool $validate Validate the field before upload.
5807
- * $type bool $typehook Apply a hook on the field while typing.
5808
- * $type string $hintposition The position of the hint text in
5809
- * relation to the field.
5810
- * $type string $default The default value of the field.
5811
- * $type string $data A data property specific per field type.
5812
- * $type string $group The field is grouped with other fields.
5813
- * $type string $format Field format, specific per type.
5814
- * }
5815
- * }
5816
- */
5817
- function wfu_parse_userdata_attribute($value){
5818
- $fields = array();
5819
- //read defaults
5820
- $definitions_unindexed = wfu_formfield_definitions();
5821
- $defaults = array();
5822
- foreach ( $definitions_unindexed as $def ) {
5823
- $default = array();
5824
- $default["type"] = $def["type"];
5825
- $default["label"] = $def["label"];
5826
- $default["labelposition"] = "".substr($def["labelposition"], 5);
5827
- $default["required"] = ( substr($def["required"], 5) == "true" );
5828
- $default["donotautocomplete"] = ( substr($def["donotautocomplete"], 5) == "true" );
5829
- $default["validate"] = ( substr($def["validate"], 5) == "true" );
5830
- $default["typehook"] = ( substr($def["typehook"], 5) == "true" );
5831
- $default["hintposition"] = "".substr($def["hintposition"], 5);
5832
- $default["default"] = "".substr($def["default"], 5);
5833
- $default["data"] = "".substr($def["data"], 5);
5834
- $default["group"] = "".substr($def["group"], 5);
5835
- $default["format"] = "".substr($def["format"], 5);
5836
- $defaults[$def["type"]] = $default;
5837
- }
5838
- // $fields_arr = explode("/", $value);
5839
- $value = str_replace("/", "[/]", $value);
5840
- $value = preg_replace_callback("/\(.*\)/", "wfu_preg_replace_callback_func", $value);
5841
- $fields_arr = explode("[/]", $value);
5842
- //parse shortcode attribute to $fields
5843
- foreach ( $fields_arr as $field_raw ) {
5844
- $field_raw = trim($field_raw);
5845
- $fieldprops = $defaults["text"];
5846
- //read old default attribute
5847
- if ( substr($field_raw, 0, 1) == "*" ) {
5848
- $fieldprops["required"] = true;
5849
- $field_raw = substr($field_raw, 1);
5850
- }
5851
- $field_parts = explode("|", $field_raw);
5852
- //proceed if the first part, which is the label, is non-empty
5853
- if ( trim($field_parts[0]) != "" ) {
5854
- //get type, if exists, in order to adjust defaults
5855
- $type_key = -1;
5856
- $new_type = "";
5857
- foreach ( $field_parts as $key => $part ) {
5858
- $part = ltrim($part);
5859
- $flag = substr($part, 0, 2);
5860
- $val = substr($part, 2);
5861
- if ( $flag == "t:" && $key > 0 && array_key_exists($val, $defaults) ) {
5862
- $new_type = $val;
5863
- $type_key = $key;
5864
- break;
5865
- }
5866
- }
5867
- if ( $new_type != "" ) {
5868
- $fieldprops = $defaults[$new_type];
5869
- unset($field_parts[$type_key]);
5870
- }
5871
- //store label
5872
- $fieldprops["label"] = trim($field_parts[0]);
5873
- unset($field_parts[0]);
5874
- //get other properties
5875
- foreach ( $field_parts as $part ) {
5876
- $part = ltrim($part);
5877
- $flag = substr($part, 0, 2);
5878
- $val = "".substr($part, 2);
5879
- if ( $flag == "s:" ) $fieldprops["labelposition"] = $val;
5880
- elseif ( $flag == "r:" ) $fieldprops["required"] = ( $val == "1" );
5881
- elseif ( $flag == "a:" ) $fieldprops["donotautocomplete"] = ( $val == "1" );
5882
- elseif ( $flag == "v:" ) $fieldprops["validate"] = ( $val == "1" );
5883
- elseif ( $flag == "d:" ) $fieldprops["default"] = $val;
5884
- elseif ( $flag == "l:" ) $fieldprops["data"] = $val;
5885
- elseif ( $flag == "g:" ) $fieldprops["group"] = $val;
5886
- elseif ( $flag == "f:" ) $fieldprops["format"] = $val;
5887
- elseif ( $flag == "p:" ) $fieldprops["hintposition"] = $val;
5888
- elseif ( $flag == "h:" ) $fieldprops["typehook"] = ( $val == "1" );
5889
- }
5890
- array_push($fields, $fieldprops);
5891
- }
5892
- }
5893
-
5894
- return $fields;
5895
- }
5896
-
5897
- /**
5898
- * Checke and Remove Honeypot Fields.
5899
- *
5900
- * The plugin uses honeypot userdata fields as an additional security measure
5901
- * against bots. A honeypot is a field which is not visible to the user, but it
5902
- * can be filled with a value. A human will not see the field, so it will not
5903
- * fill it with data. On the other hand, a bot does not care about visibility.
5904
- * If the field has a common name, like 'url' or 'website' it will think that it
5905
- * is a normal field and will fill it with data. In this case the upload will
5906
- * fail silently (the bot will think that it succeeded). If the honeypot field
5907
- * is empty, then the upload will continue normally, however it will be removed
5908
- * from userdata fields list because it is not necessary anymore.
5909
- *
5910
- * @since 4.10.1
5911
- *
5912
- * @param array $userdata_fields An array of userdata fields.
5913
- * @param string $post_key A string to locate the value of the honeypot field
5914
- * in received POST parameters.
5915
- *
5916
- * @return bool True if the honeypot field is filled, false otherwise.
5917
- */
5918
- function wfu_check_remove_honeypot_fields(&$userdata_fields, $post_key) {
5919
- //check if honeypot userdata fields have been added to the form and if they
5920
- //contain any data
5921
- $honeypot_filled = false;
5922
- foreach ( $userdata_fields as $userdata_key => $userdata_field ) {
5923
- if ( $userdata_field["type"] == "honeypot" ) {
5924
- $val = ( isset($_POST[$post_key.$userdata_key]) ? $_POST[$post_key.$userdata_key] : "" );
5925
- //if a non-zero value has been passed to the server, this means
5926
- //that it has been filled by a bot
5927
- if ( $val != "" ) {
5928
- $honeypot_filled = true;
5929
- break;
5930
- }
5931
- //if the honeypot field is empty then remove it from
5932
- //userdata_fields array because we do not want to be stored
5933
- else unset($userdata_fields[$userdata_key]);
5934
- }
5935
- }
5936
-
5937
- //if any honeypot field has been filled then return true to denote that
5938
- //the upload must be aborted
5939
- return $honeypot_filled;
5940
- }
5941
-
5942
- //************************* Cookie Functions ***********************************
5943
-
5944
- /**
5945
- * Read Session Cookie.
5946
- *
5947
- * This function reads the session cookie of the plugin that is used to store
5948
- * user state information when User State handler is set to 'dboption'.
5949
- *
5950
- * @since 4.12.0
5951
- *
5952
- * @return string The session ID.
5953
- */
5954
- function wfu_get_session_cookie() {
5955
- return isset($_COOKIE[WPFILEUPLOAD_COOKIE]) ? wfu_sanitize_code(substr($_COOKIE[WPFILEUPLOAD_COOKIE], 0, 32)) : "";
5956
- }
5957
-
5958
- /**
5959
- * Set Session Cookie.
5960
- *
5961
- * This function sets the session cookie of the plugin that is used to store
5962
- * user state information when User State handler is set to 'dboption'. This
5963
- * function generates a session ID that composes of a random 32-digit string.
5964
- *
5965
- * @since 4.12.0
5966
- *
5967
- * @redeclarable
5968
- */
5969
- function wfu_set_session_cookie() {
5970
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5971
- if ( !headers_sent() ) {
5972
- $cookie = wfu_create_random_string(32);
5973
- setcookie(
5974
- WPFILEUPLOAD_COOKIE,
5975
- $cookie,
5976
- time() + intval(WFU_VAR("WFU_US_COOKIE_LIFE")) * 3600,
5977
- COOKIEPATH ? COOKIEPATH : '/',
5978
- COOKIE_DOMAIN,
5979
- false,
5980
- false
5981
- );
5982
- $_COOKIE[WPFILEUPLOAD_COOKIE] = $cookie;
5983
- }
5984
- }
5985
-
5986
- //********************* User State Functions ***********************************
5987
-
5988
- /**
5989
- * Initialize User State.
5990
- *
5991
- * This function initializes the user state. If user state handler is 'dboption'
5992
- * then it sets the session cookie. If it is 'session' it starts the session
5993
- * now or on demand, depending on 'WFU_US_SESSION_LEGACY' variable.
5994
- *
5995
- * @since 4.12.0
5996
- *
5997
- * @global string $wfu_user_state_handler The defined User State handler.
5998
- *
5999
- * @redeclarable
6000
- */
6001
- function wfu_initialize_user_state() {
6002
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6003
- global $wfu_user_state_handler;
6004
- if ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "cookies" ) {
6005
- if ( wfu_get_session_cookie() == "" ) wfu_set_session_cookie();
6006
- }
6007
- elseif ( WFU_VAR("WFU_US_SESSION_LEGACY") == "true" && !headers_sent() && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) ) { session_start(); }
6008
- }
6009
-
6010
- /**
6011
- * Check if User State Variable Exists.
6012
- *
6013
- * This function checks if a variable exists in User State.
6014
- *
6015
- * @since 4.3.2
6016
- *
6017
- * @global string $wfu_user_state_handler The defined User State handler.
6018
- *
6019
- * @redeclarable
6020
- *
6021
- * @param string $var The variable to check.
6022
- *
6023
- * @return bool True if the variable exists, false otherwise.
6024
- */
6025
- function WFU_USVAR_exists($var) {
6026
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6027
- global $wfu_user_state_handler;
6028
- if ( $wfu_user_state_handler == "dboption" )
6029
- return ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USVAR_exists_dboption($var) : WFU_USVAR_exists_dboption_old($var) );
6030
- else return WFU_USVAR_exists_session($var);
6031
- }
6032
-
6033
- /**
6034
- * Get Variable From User State.
6035
- *
6036
- * This function gets the value of a variable from User State.
6037
- *
6038
- * @since 4.3.2
6039
- *
6040
- * @global string $wfu_user_state_handler The defined User State handler.
6041
- *
6042
- * @redeclarable
6043
- *
6044
- * @param string $var The variable to get.
6045
- *
6046
- * @return mixed The value of the variable.
6047
- */
6048
- function WFU_USVAR($var) {
6049
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6050
- global $wfu_user_state_handler;
6051
- if ( $wfu_user_state_handler == "dboption" )
6052
- return ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USVAR_dboption($var) : WFU_USVAR_dboption_old($var) );
6053
- else return WFU_USVAR_session($var);
6054
- }
6055
-
6056
- /**
6057
- * Get All User State Variables.
6058
- *
6059
- * This function gets the values of all User State variables.
6060
- *
6061
- * @since 4.3.2
6062
- *
6063
- * @global string $wfu_user_state_handler The defined User State handler.
6064
- *
6065
- * @redeclarable
6066
- *
6067
- * @return array An array of all User State variables.
6068
- */
6069
- function WFU_USALL() {
6070
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6071
- global $wfu_user_state_handler;
6072
- if ( $wfu_user_state_handler == "dboption" )
6073
- return ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USALL_dboption() : WFU_USALL_dboption_old() );
6074
- else return WFU_USALL_session();
6075
- }
6076
-
6077
- /**
6078
- * Store Variable In User State.
6079
- *
6080
- * This function stores the value of a variable in User State.
6081
- *
6082
- * @since 4.3.2
6083
- *
6084
- * @global string $wfu_user_state_handler The defined User State handler.
6085
- *
6086
- * @redeclarable
6087
- *
6088
- * @param string $var The variable to store.
6089
- * @param mixed $value The value of the variable.
6090
- */
6091
- function WFU_USVAR_store($var, $value) {
6092
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6093
- global $wfu_user_state_handler;
6094
- if ( $wfu_user_state_handler == "dboption" )
6095
- ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USVAR_store_dboption($var, $value) : WFU_USVAR_store_dboption_old($var, $value) );
6096
- else WFU_USVAR_store_session($var, $value);
6097
- }
6098
-
6099
- /**
6100
- * Remove Variable From User State.
6101
- *
6102
- * This function removes a variable from User State.
6103
- *
6104
- * @since 4.3.2
6105
- *
6106
- * @global string $wfu_user_state_handler The defined User State handler.
6107
- *
6108
- * @redeclarable
6109
- *
6110
- * @param string $var The variable to remove.
6111
- */
6112
- function WFU_USVAR_unset($var) {
6113
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6114
- global $wfu_user_state_handler;
6115
- if ( $wfu_user_state_handler == "dboption" )
6116
- ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USVAR_unset_dboption($var) : WFU_USVAR_unset_dboption_old($var) );
6117
- else WFU_USVAR_unset_session($var);
6118
- }
6119
-
6120
- /**
6121
- * Check if Session Variable Exists.
6122
- *
6123
- * This function checks if a variable exists in Session.
6124
- *
6125
- * @since 4.4.0
6126
- *
6127
- * @param string $var The variable to check.
6128
- *
6129
- * @return bool True if the variable exists, false otherwise.
6130
- */
6131
- function WFU_USVAR_exists_session($var) {
6132
- $session_id = session_id();
6133
- $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6134
- if ( $open_session ) session_start();
6135
- $exists = isset($_SESSION[$var]);
6136
- if ( $open_session ) session_write_close();
6137
- return $exists;
6138
- }
6139
-
6140
- /**
6141
- * Get Variable From Session.
6142
- *
6143
- * This function gets the value of a variable from Session.
6144
- *
6145
- * @since 4.4.0
6146
- *
6147
- * @param string $var The variable to get.
6148
- *
6149
- * @return mixed The value of the variable.
6150
- */
6151
- function WFU_USVAR_session($var) {
6152
- $session_id = session_id();
6153
- $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6154
- if ( $open_session ) session_start();
6155
- $value = $_SESSION[$var];
6156
- if ( $open_session ) session_write_close();
6157
- return $value;
6158
- }
6159
-
6160
- /**
6161
- * Get All Session Variables.
6162
- *
6163
- * This function gets the values of all Session variables.
6164
- *
6165
- * @since 4.4.0
6166
- *
6167
- * @return array An array of all Session variables.
6168
- */
6169
- function WFU_USALL_session() {
6170
- $session_id = session_id();
6171
- $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6172
- if ( $open_session ) session_start();
6173
- $all = $_SESSION;
6174
- if ( $open_session ) session_write_close();
6175
- return $all;
6176
- }
6177
-
6178
- /**
6179
- * Store Variable In Session.
6180
- *
6181
- * This function stores the value of a variable in Session.
6182
- *
6183
- * @since 4.4.0
6184
- *
6185
- * @param string $var The variable to store.
6186
- * @param mixed $value The value of the variable.
6187
- */
6188
- function WFU_USVAR_store_session($var, $value) {
6189
- $session_id = session_id();
6190
- $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6191
- if ( $open_session ) session_start();
6192
- $_SESSION[$var] = $value;
6193
- if ( $open_session ) session_write_close();
6194
- }
6195
-
6196
- /**
6197
- * Remove Variable From Session.
6198
- *
6199
- * This function removes a variable from Session.
6200
- *
6201
- * @since 4.4.0
6202
- *
6203
- * @param string $var The variable to remove.
6204
- */
6205
- function WFU_USVAR_unset_session($var) {
6206
- $session_id = session_id();
6207
- $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6208
- if ( $open_session ) session_start();
6209
- unset($_SESSION[$var]);
6210
- if ( $open_session ) session_write_close();
6211
- }
6212
-
6213
- /**
6214
- * Get Session ID.
6215
- *
6216
- * This function gets session ID depending on the user state handler and
6217
- * relevant advanced variables.
6218
- *
6219
- * @since 4.12.0
6220
- *
6221
- * @global string $wfu_user_state_handler The defined User State handler.
6222
- *
6223
- * @return string The Session ID.
6224
- */
6225
- function wfu_get_session_id() {
6226
- global $wfu_user_state_handler;
6227
- $key = "";
6228
- if ( ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "session" ) || $wfu_user_state_handler != "dboption" ) {
6229
- $key = session_id();
6230
- if ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) ) {
6231
- session_start();
6232
- $key = session_id();
6233
- session_write_close();
6234
- }
6235
- }
6236
- elseif ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "cookies" )
6237
- $key = wfu_get_session_cookie();
6238
- return $key;
6239
- }
6240
-
6241
- /**
6242
- * Flatten Session ID.
6243
- *
6244
- * This function removes dots and other symbols from session ID.
6245
- *
6246
- * @since 4.4.0
6247
- *
6248
- * @return string Flattened Session ID.
6249
- */
6250
- function wfu_get_safe_session_id() {
6251
- return preg_replace("/[^a-z0-9_]/", "", strtolower(wfu_get_session_id()));
6252
- }
6253
-
6254
- /**
6255
- * Get DB Option Data.
6256
- *
6257
- * This function gets User State data for a specific session, stored in the
6258
- * website's database.
6259
- *
6260
- * @since 4.4.0
6261
- *
6262
- * @param string $id The Session ID.
6263
- * @param string $default Optional. Default value for the data.
6264
- * @param string $type Optional. The type of data value.
6265
- *
6266
- * @return array The DB Option data.
6267
- */
6268
- function wfu_get_US_dboption_data($id, $default = false, $type = "array") {
6269
- if ( $id == "" ) return false;
6270
- return wfu_get_option("wfu_userstate_".$id, $default, $type);
6271
- }
6272
-
6273
- /**
6274
- * Update DB Option Time.
6275
- *
6276
- * This function updates the time that DB Option data of a specific Session
6277
- * where last used.
6278
- *
6279
- * @since 4.4.0
6280
- *
6281
- * @param string $id The Session ID.
6282
- */
6283
- function wfu_update_US_dboption_time($id) {
6284
- $list = wfu_get_option("wfu_userstate_list", array());
6285
- $list[$id] = time();
6286
- wfu_update_option("wfu_userstate_list", $list);
6287
- }
6288
-
6289
- /**
6290
- * Check if Variable Exists in DB Option (old handler).
6291
- *
6292
- * This function checks if a variable exists in DB Option.
6293
- *
6294
- * @since 4.4.0
6295
- *
6296
- * @param string $var The variable to check.
6297
- *
6298
- * @return bool True if the variable exists, false otherwise.
6299
- */
6300
- function WFU_USVAR_exists_dboption_old($var) {
6301
- $id = wfu_get_safe_session_id();
6302
- $data = wfu_get_US_dboption_data($id);
6303
- if ( $data === false ) return false;
6304
- wfu_update_US_dboption_time($id);
6305
- return isset($data[$var]);
6306
- }
6307
-
6308
- /**
6309
- * Check if Variable Exists in DB Option.
6310
- *
6311
- * This function checks if a variable exists in DB Option.
6312
- *
6313
- * @since 4.4.0
6314
- *
6315
- * @param string $var The variable to check.
6316
- *
6317
- * @return bool True if the variable exists, false otherwise.
6318
- */
6319
- function WFU_USVAR_exists_dboption($var) {
6320
- $id = wfu_get_safe_session_id();
6321
- if ( $id == "" ) return false;
6322
- $exists = wfu_option_item_exists("wfu_userstate_".$id, $var);
6323
- wfu_update_US_dboption_time($id);
6324
- if ( $exists === null ) return false;
6325
- else return $exists;
6326
- }
6327
-
6328
- /**
6329
- * Get Variable From DB Option (old handler).
6330
- *
6331
- * This function gets the value of a variable from DB Option.
6332
- *
6333
- * @since 4.4.0
6334
- *
6335
- * @param string $var The variable to get.
6336
- *
6337
- * @return mixed The value of the variable.
6338
- */
6339
- function WFU_USVAR_dboption_old($var) {
6340
- $id = wfu_get_safe_session_id();
6341
- $data = wfu_get_US_dboption_data($id);
6342
- if ( $data === false ) return "";
6343
- wfu_update_US_dboption_time($id);
6344
- return $data[$var];
6345
- }
6346
-
6347
- /**
6348
- * Get Variable From DB Option.
6349
- *
6350
- * This function gets the value of a variable from DB Option.
6351
- *
6352
- * @since 4.4.0
6353
- *
6354
- * @param string $var The variable to get.
6355
- *
6356
- * @return mixed The value of the variable.
6357
- */
6358
- function WFU_USVAR_dboption($var) {
6359
- $id = wfu_get_safe_session_id();
6360
- if ( $id == "" ) return "";
6361
- $value = wfu_get_option_item("wfu_userstate_".$id, $var);
6362
- wfu_update_US_dboption_time($id);
6363
- if ( $value === null ) return "";
6364
- else return wfu_decode_array_from_string($value);
6365
- }
6366
-
6367
- /**
6368
- * Get All DB Option Variables (old handler).
6369
- *
6370
- * This function gets the values of all DB Option variables.
6371
- *
6372
- * @since 4.4.0
6373
- *
6374
- * @return array An array of all DB Option variables.
6375
- */
6376
- function WFU_USALL_dboption_old() {
6377
- $id = wfu_get_safe_session_id();
6378
- $data = wfu_get_US_dboption_data($id);
6379
- if ( $data === false ) return array();
6380
- wfu_update_US_dboption_time($id);
6381
- return $data;
6382
- }
6383
-
6384
- /**
6385
- * Get All DB Option Variables.
6386
- *
6387
- * This function gets the values of all DB Option variables.
6388
- *
6389
- * @since 4.4.0
6390
- *
6391
- * @return array An array of all DB Option variables.
6392
- */
6393
- function WFU_USALL_dboption() {
6394
- $id = wfu_get_safe_session_id();
6395
- $data = wfu_get_US_dboption_data($id, false, "string");
6396
- if ( $data === null ) return array();
6397
- wfu_update_US_dboption_time($id);
6398
- $arr = preg_split("/\[([^\]]*\][^{]*){[^}]*}/", $data, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
6399
- $data_arr = array();
6400
- foreach ( $arr as $item ) {
6401
- $parts = explode("]", $item);
6402
- if ( count($parts) == 2 )
6403
- $data_arr[$parts[0]] = wfu_decode_array_from_string($parts[1]);
6404
- }
6405
- return $data_arr;
6406
- }
6407
-
6408
- /**
6409
- * Store Variable In DB Option (old handler).
6410
- *
6411
- * This function stores the value of a variable in DB Option.
6412
- *
6413
- * @since 4.4.0
6414
- *
6415
- * @param string $var The variable to store.
6416
- * @param mixed $value The value of the variable.
6417
- */
6418
- function WFU_USVAR_store_dboption_old($var, $value) {
6419
- $id = wfu_get_safe_session_id();
6420
- $data = wfu_get_US_dboption_data($id, array());
6421
- if ( $data === false ) return;
6422
- $data[$var] = $value;
6423
- wfu_update_option("wfu_userstate_".$id, $data);
6424
- wfu_update_US_dboption_time($id);
6425
- wfu_update_US_dboption_list();
6426
- }
6427
-
6428
- /**
6429
- * Store Variable In DB Option.
6430
- *
6431
- * This function stores the value of a variable in DB Option.
6432
- *
6433
- * @since 4.4.0
6434
- *
6435
- * @param string $var The variable to store.
6436
- * @param mixed $value The value of the variable.
6437
- */
6438
- function WFU_USVAR_store_dboption($var, $value) {
6439
- $id = wfu_get_safe_session_id();
6440
- if ( $id == "" ) return;
6441
- wfu_update_option_item("wfu_userstate_".$id, $var, wfu_encode_array_to_string($value));
6442
- wfu_update_US_dboption_time($id);
6443
- wfu_update_US_dboption_list();
6444
- }
6445
-
6446
- /**
6447
- * Remove Variable From DB Option (old handler).
6448
- *
6449
- * This function removes a variable from DB Option.
6450
- *
6451
- * @since 4.4.0
6452
- *
6453
- * @param string $var The variable to remove.
6454
- */
6455
- function WFU_USVAR_unset_dboption_old($var) {
6456
- $id = wfu_get_safe_session_id();
6457
- $data = wfu_get_US_dboption_data($id);
6458
- if ( $data === false ) return;
6459
- unset($data[$var]);
6460
- wfu_update_option("wfu_userstate_".$id, $data);
6461
- wfu_update_US_dboption_time($id);
6462
- }
6463
-
6464
- /**
6465
- * Remove Variable From DB Option.
6466
- *
6467
- * This function removes a variable from DB Option.
6468
- *
6469
- * @since 4.4.0
6470
- *
6471
- * @param string $var The variable to remove.
6472
- */
6473
- function WFU_USVAR_unset_dboption($var) {
6474
- $id = wfu_get_safe_session_id();
6475
- if ( $id == "" ) return;
6476
- wfu_delete_option_item("wfu_userstate_".$id, $var);
6477
- wfu_update_US_dboption_time($id);
6478
- }
6479
-
6480
- /**
6481
- * Update DB Option List.
6482
- *
6483
- * This function checks when all DB Option Data were last used. DB Option data
6484
- * that were last used before a long time, means that their Session has expired,
6485
- * so they are not useful anymore and will be removed.
6486
- *
6487
- * @since 4.4.0
6488
- */
6489
- function wfu_update_US_dboption_list() {
6490
- $last_check_interval = time() - wfu_get_option("wfu_userstate_list_last_check", 0);
6491
- $limit = WFU_VAR("WFU_US_DBOPTION_CHECK");
6492
- if ( $last_check_interval < $limit ) return;
6493
-
6494
- $list = wfu_get_option("wfu_userstate_list", array());
6495
- $changed = false;
6496
- $limit = WFU_VAR("WFU_US_DBOPTION_LIFE");
6497
- foreach ( $list as $id => $time ) {
6498
- $interval = time() - $time;
6499
- if ( $interval > $limit ) {
6500
- $changed = true;
6501
- unset($list[$id]);
6502
- wfu_delete_option("wfu_userstate_".$id);
6503
- }
6504
- }
6505
- if ( $changed ) wfu_update_option("wfu_userstate_list", $list);
6506
- wfu_update_option("wfu_userstate_list_last_check", time());
6507
- }
6508
-
6509
- //********************* Javascript Related Functions ****************************************************************************************************
6510
-
6511
- /**
6512
- * Inject Javascript Code.
6513
- *
6514
- * This function generates HTML output for injecting Javascript code. After
6515
- * execution of the code, the HTML output is erased leaving no traces.
6516
- *
6517
- * @since 3.3.0
6518
- *
6519
- * @param string $code The Javascript code to inject.
6520
- *
6521
- * @return string The HTML output.
6522
- */
6523
- function wfu_inject_js_code($code){
6524
- $id = 'code_'.wfu_create_random_string(8);
6525
- $html = '<div id="'.$id.'" style="display:none;"><script type="text/javascript">'.$code.'</script><script type="text/javascript">var div = document.getElementById("'.$id.'"); div.parentNode.removeChild(div);</script></div>';
6526
-
6527
- return $html;
6528
- }
6529
-
6530
- //********************* Consent Functions ****************************************************************************************************
6531
-
6532
- /**
6533
- * Get Consent Status of User.
6534
- *
6535
- * This function gets the consent status of a user.
6536
- *
6537
- * @since 4.5.0
6538
- *
6539
- * @param WPUser $user The user to get its consent status.
6540
- *
6541
- * @return string The consent status of the user:
6542
- * "1": the user has given its consent.
6543
- * "0": the user has not given its consent.
6544
- * "": the user has not answered to consent question.
6545
- */
6546
- function wfu_check_user_consent($user) {
6547
- //returns empty string if user has not completed consent question yet, "1"
6548
- //if user has given consent, "0" otherwise
6549
- $result = "";
6550
- if ( $user->ID > 0 ) {
6551
- //check in user meta for consent
6552
- $data = get_the_author_meta( 'WFU_Consent_Data', $user->ID );
6553
- if ( $data && isset($data["consent_status"]) )
6554
- $result = $data["consent_status"];
6555
- }
6556
- else {
6557
- //check in user state for consent
6558
- if ( WFU_USVAR_exists('WFU_Consent_Data') ) {
6559
- $data = WFU_USVAR('WFU_Consent_Data');
6560
- if ( isset($data["consent_status"]) )
6561
- $result = $data["consent_status"];
6562
- }
6563
- }
6564
-
6565
- return $result;
6566
- }
6567
-
6568
- /**
6569
- * Update Consent Status of User From Front-End.
6570
- *
6571
- * This function updates the consent status of a user when asked through an
6572
- * upload form. If user is logged in, then consent status is stored in its
6573
- * profile. If the user is not logged in, then consent status is store in User
6574
- * State.
6575
- *
6576
- * @since 4.5.0
6577
- *
6578
- * @param WPUser $user The user to store its consent status.
6579
- * @param string $consent_result The new consent status. It can be "yes", "no"
6580
- * or "".
6581
- */
6582
- function wfu_update_user_consent($user, $consent_result) {
6583
- if ( $user->ID > 0 ) {
6584
- //check in user meta for consent
6585
- $data = get_the_author_meta( 'WFU_Consent_Data', $user->ID );
6586
- if ( !$data ) $data = array();
6587
- $data["consent_status"] = ( $consent_result == "yes" ? "1" : ( $consent_result == "no" ? "0" : "" ) );
6588
- update_user_meta( $user->ID, 'WFU_Consent_Data', $data );
6589
- }
6590
- else {
6591
- //check in user state for consent
6592
- if ( WFU_USVAR_exists('WFU_Consent_Data') ) $data = WFU_USVAR('WFU_Consent_Data');
6593
- else $data = array();
6594
- $data["consent_status"] = ( $consent_result == "yes" ? "1" : ( $consent_result == "no" ? "0" : "" ) );
6595
- WFU_USVAR_store( 'WFU_Consent_Data', $data );
6596
- }
6597
- }
6598
-
6599
- /**
6600
- * Show Consent Status Fields in User's Profile Page.
6601
- *
6602
- * This function outputs the HTML code of the consent status fields shown in
6603
- * user's profile page.
6604
- *
6605
- * @since 4.5.0
6606
- *
6607
- * @param WPUser $user The involved user.
6608
- */
6609
- function wfu_show_consent_profile_fields($user) {
6610
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
6611
- if ( $plugin_options["personaldata"] != "1" ) return;
6612
-
6613
- $data = get_the_author_meta( 'WFU_Consent_Data', $user->ID );
6614
- if ( !$data ) $data = array();
6615
- if ( !isset($data["consent_status"]) ) $data["consent_status"] = "";
6616
- $status = $data["consent_status"];
6617
-
6618
- $echo_str = "\n\t".'<h3>'.esc_html__( 'Wordpress File Upload Consent Status', 'wp-file-upload' ).'</h3>';
6619
- $echo_str .= "\n\t".'<table class="form-table">';
6620
- $echo_str .= "\n\t\t".'<tr>';
6621
- $echo_str .= "\n\t\t\t".'<th><label>'.esc_html__( 'Consent Status', 'wp-file-upload' ).'</label></th>';
6622
- $echo_str .= "\n\t\t\t".'<td>';
6623
- $echo_str .= "\n\t\t\t\t".'<label style="font-weight: bold;">'.( $status == "1" ? esc_html__( 'You have given your consent to store personal data.', 'wp-file-upload' ) : ( $status == "0" ? esc_html__( 'You have denied to store personal data.', 'wp-file-upload' ) : esc_html__( 'You have not answered to consent yet.', 'wp-file-upload' ) ) ).'</label>';
6624
- $echo_str .= "\n\t\t\t".'</td>';
6625
- $echo_str .= "\n\t\t".'</tr>';
6626
- $echo_str .= "\n\t\t".'<tr>';
6627
- $echo_str .= "\n\t\t\t".'<th></th>';
6628
- $echo_str .= "\n\t\t\t".'<td>';
6629
- $echo_str .= "\n\t\t\t\t".'<label>'.esc_html__( 'Change status to', 'wp-file-upload' ).'</label>';
6630
- $echo_str .= "\n\t\t\t\t".'<select name="consent_status">';
6631
- $echo_str .= "\n\t\t\t\t\t".'<option value="-1" selected="selected">'.esc_html__( 'No change', 'wp-file-upload' ).'</option>';
6632
- if ( $status == "1" ) {
6633
- $echo_str .= "\n\t\t\t\t\t".'<option value="0">'.esc_html__( 'Revoke Consent', 'wp-file-upload' ).'</option>';
6634
- $echo_str .= "\n\t\t\t\t\t".'<option value="">'.esc_html__( 'Clear Consent', 'wp-file-upload' ).'</option>';
6635
- }
6636
- elseif ( $status == "0" ) {
6637
- $echo_str .= "\n\t\t\t\t\t".'<option value="1">'.esc_html__( 'Give Consent', 'wp-file-upload' ).'</option>';
6638
- $echo_str .= "\n\t\t\t\t\t".'<option value="">'.esc_html__( 'Clear Consent', 'wp-file-upload' ).'</option>';
6639
- }
6640
- if ( $status == "" ) {
6641
- $echo_str .= "\n\t\t\t\t\t".'<option value="0">'.esc_html__( 'Revoke Consent', 'wp-file-upload' ).'</option>';
6642
- $echo_str .= "\n\t\t\t\t\t".'<option value="1">'.esc_html__( 'Give Consent', 'wp-file-upload' ).'</option>';
6643
- }
6644
- $echo_str .= "\n\t\t\t\t".'</select>';
6645
- $echo_str .= "\n\t\t\t".'</td>';
6646
- $echo_str .= "\n\t\t".'</tr>';
6647
- /*
6648
- if ( current_user_can( 'manage_options' ) ) {
6649
- $echo_str .= "\n\t\t".'<tr>';
6650
- $echo_str .= "\n\t\t\t".'<th><label>'.esc_html__( 'Personal Data Operations', 'wp-file-upload' ).'</label></th>';
6651
- $echo_str .= "\n\t\t\t".'<td>';
6652
- $echo_str .= "\n\t\t\t\t".'<input id="wfu_download_file_nonce" type="hidden" value="'.wp_create_nonce('wfu_download_file_invoker').'" />';
6653
- $echo_str .= "\n\t\t\t\t".'<button type="button" class="button" onclick="wfu_download_file(\'exportdata\', 1);">'.esc_html__( 'Export User Data', 'wp-file-upload' ).'</button>';
6654
- $echo_str .= "\n\t\t\t".'</td>';
6655
- $echo_str .= "\n\t\t".'</tr>';
6656
- }*/
6657
- $echo_str .= "\n\t".'</table>';
6658
-
6659
- echo $echo_str;
6660
- }
6661
-
6662
- /**
6663
- * Update Consent Status of User From Back-End.
6664
- *
6665
- * This function updates the consent status of a user from its User Profile
6666
- * page.
6667
- *
6668
- * @since 4.5.0
6669
- *
6670
- * @param int $user_id The ID of the involved user.
6671
- */
6672
- function wfu_update_consent_profile_fields( $user_id ) {
6673
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
6674
- if ( $plugin_options["personaldata"] != "1" ) return false;
6675
-
6676
- if ( ! current_user_can( 'edit_user', $user_id ) ) {
6677
- return false;
6678
- }
6679
-
6680
- $status = $_POST['consent_status'];
6681
- if ( $status == '1' || $status == '0' || $status == '' ) {
6682
- $data = get_the_author_meta( 'WFU_Consent_Data', $user_id );
6683
- if ( !$data ) $data = array();
6684
- $data["consent_status"] = $status;
6685
- update_user_meta( $user_id, 'WFU_Consent_Data', $data );
6686
- }
6687
- }
6688
-
6689
- //********************* Browser Functions ****************************************************************************************************
6690
-
6691
- /**
6692
- * Store Front-End File Viewer Shortcode Attributes.
6693
- *
6694
- * This function stores the shortcode attributes of a front-end file viewer in
6695
- * User Space for future retrieval.
6696
- *
6697
- * @since 3.6.1
6698
- *
6699
- * @param string $params The front-end file viewer shortcode attributes.
6700
- *
6701
- * @return string A unique code representing the stored shortcode.
6702
- */
6703
- function wfu_safe_store_browser_params($params) {
6704
- $code = wfu_create_random_string(16);
6705
- $safe_storage = ( WFU_USVAR_exists('wfu_browser_actions_safe_storage') ? WFU_USVAR('wfu_browser_actions_safe_storage') : array() );
6706
- $safe_storage[$code] = $params;
6707
- WFU_USVAR_store('wfu_browser_actions_safe_storage', $safe_storage);
6708
- return $code;
6709
- }
6710
-
6711
- /**
6712
- * Retrieve Stored Front-End File Viewer Shortcode Attributes.
6713
- *
6714
- * This function retrieved stored shortcode attributes of a front-end file
6715
- * viewer from User Space.
6716
- *
6717
- * @since 3.6.1
6718
- *
6719
- * @param string $code A unique code representing the stored shortcode.
6720
- *
6721
- * @return string The stored shortcode attributes.
6722
- */
6723
- function wfu_get_browser_params_from_safe($code) {
6724
- //sanitize $code
6725
- $code = wfu_sanitize_code($code);
6726
- if ( $code == "" ) return false;
6727
- //return params from session variable, if exists
6728
- if ( !WFU_USVAR_exists('wfu_browser_actions_safe_storage') ) return false;
6729
- $safe_storage = WFU_USVAR('wfu_browser_actions_safe_storage');
6730
- if ( !isset($safe_storage[$code]) ) return false;
6731
- return $safe_storage[$code];
6732
- }
6733
-
6734
- //********************* POST/GET Requests Functions ****************************************************************************************************
6735
-
6736
- /**
6737
- * Add Proxy in HTTP Request.
6738
- *
6739
- * This function adds proxy information inside an HTTP request configuration, if
6740
- * proxy information is defined inside the website's configuration and if it is
6741
- * active.
6742
- *
6743
- * @since 4.10.0
6744
- *
6745
- * @param array $config An HTTP request configuration structure.
6746
- *
6747
- * @return bool True if proxy is enabled and added, false otherwise.
6748
- */
6749
- function wfu_add_proxy_param(&$config) {
6750
- //include proxy support
6751
- $proxy = new \WP_HTTP_Proxy();
6752
- $proxy_enabled = $proxy->is_enabled();
6753
- if ( $proxy_enabled ) {
6754
- $config['proxy']['http'] = 'http://'.( $proxy->use_authentication() ? $proxy->authentication().'@' : '' ).$proxy->host().":".$proxy->port();
6755
- $config['proxy']['https'] = 'http://'.( $proxy->use_authentication() ? $proxy->authentication().'@' : '' ).$proxy->host().":".$proxy->port();
6756
- //make sure that wildcard asterisks (*) are removed from bypass hosts
6757
- //to make it compatible with Guzzle format
6758
- if ( defined('WP_PROXY_BYPASS_HOSTS') ) $config['proxy']['no'] = preg_split('|,\s*|', str_replace('*', '', WP_PROXY_BYPASS_HOSTS));
6759
- }
6760
-
6761
- return $proxy_enabled;
6762
- }
6763
-
6764
- /**
6765
- * Parse Socket HTTP Response.
6766
- *
6767
- * This function tries to decode an HTTP response received through sockets and
6768
- * return the clean response data.
6769
- *
6770
- * @since 3.10.0
6771
- *
6772
- * @param string $response The raw sockets HTTP response.
6773
- *
6774
- * @return string The clean HTTP response data.
6775
- */
6776
- function wfu_decode_socket_response($response) {
6777
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6778
- $ret = "";
6779
- if (0 === strpos($response, 'HTTP/1.1 200 OK')) {
6780
- $parts = preg_split("#\n\s*\n#Uis", $response);
6781
- if ( count($parts) > 1 ) {
6782
- $rawheader = strtolower(preg_replace("/\s/", "", $parts[0]));
6783
- if ( strpos($rawheader, 'transfer-encoding:chunked') !== false ) {
6784
- $ret = "";
6785
- $pos = 0;
6786
- while ( $pos < strlen($parts[1]) ) {
6787
- $next = strpos($parts[1], "\r\n", $pos);
6788
- $len = ( $next === false || $next == $pos ? 0 : hexdec(substr($parts[1], $pos, $next - $pos)) );
6789
- if ( $len <= 0 ) break;
6790
- $ret .= substr($parts[1], $next + 2, $len);
6791
- $pos = $next + $len + 4;
6792
- }
6793
- }
6794
- else $ret = $parts[1];
6795
- }
6796
- }
6797
- return $ret;
6798
- }
6799
-
6800
- /**
6801
- * Send POST Request.
6802
- *
6803
- * This function sends a POST request using the method defined in Post Method
6804
- * option of the plugin's Settings. It is noted that the post request is
6805
- * executed synchronously. The function will wait for the response and then it
6806
- * will finish.
6807
- *
6808
- * @since 2.6.0
6809
- *
6810
- * @param string $url The destination URL of the request.
6811
- * @param array $params Parameters to pass to the POST request.
6812
- * @param bool $verifypeer Optional. Verify the peer for secure (SSL) requests.
6813
- * @param bool $internal_request Optional. True if this is an internal request
6814
- * to targetting /wp-admin area. In this case a username/password will
6815
- * also be passed to the request if Dashboard is password protected.
6816
- * @param int $timeout Optional. Timeout of the request in seconds.
6817
- *
6818
- * @return string The response of the POST request.
6819
- */
6820
- function wfu_post_request($url, $params, $verifypeer = true, $internal_request = false, $timeout = 0) {
6821
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6822
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
6823
- $default_args = array(
6824
- 'url' => $url,
6825
- 'params' => $params,
6826
- 'verifypeer' => $verifypeer,
6827
- 'internal_request' => $internal_request,
6828
- 'timeout' => $timeout
6829
- );
6830
- //check proxy
6831
- $proxy = new WP_HTTP_Proxy();
6832
- if ( isset($plugin_options['postmethod']) && $plugin_options['postmethod'] == 'curl' ) {
6833
- // POST request using CURL
6834
- $ch = curl_init($url);
6835
- $options = array(
6836
- CURLOPT_POST => true,
6837
- CURLOPT_POSTFIELDS => http_build_query($params),
6838
- CURLOPT_HTTPHEADER => array(
6839
- 'Content-Type: application/x-www-form-urlencoded'
6840
- ),
6841
- CURLINFO_HEADER_OUT => false,
6842
- CURLOPT_HEADER => false,
6843
- CURLOPT_RETURNTRANSFER => true,
6844
- CURLOPT_SSL_VERIFYPEER => $verifypeer,
6845
- CURLOPT_SSL_VERIFYHOST => ( $verifypeer ? CURLOPT_SSL_VERIFYHOST : false )
6846
- );
6847
- if ( $timeout > 0 ) $options[CURLOPT_TIMEOUT] = $timeout;
6848
- //for internal requests to /wp-admin area that is password protected
6849
- //authorization is required
6850
- if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
6851
- $options[CURLOPT_HTTPAUTH] = CURLAUTH_ANY;
6852
- $options[CURLOPT_USERPWD] = WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD");
6853
- }
6854
- if ( WFU_VAR("WFU_RELAX_CURL_VERIFY_HOST") == "true" ) $options[CURLOPT_SSL_VERIFYHOST] = false;
6855
- //configure cURL request for proxy
6856
- if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
6857
- $options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
6858
- $options[CURLOPT_PROXY] = $proxy->host().":".$proxy->port();
6859
- if ( $proxy->use_authentication() ) {
6860
- $options[CURLOPT_PROXYAUTH] = CURLAUTH_ANY;
6861
- $options[CURLOPT_PROXYUSERPWD] = $proxy->authentication();
6862
- }
6863
- }
6864
- /**
6865
- * Customize POST Request Options.
6866
- *
6867
- * This filter allows custom actions to modify the POST request options
6868
- * before the request is sent.
6869
- *
6870
- * @since 4.10.0
6871
- *
6872
- * @param array|string $options An array of POST options or request
6873
- * string.
6874
- * @param string $method The POST method. It can be 'fopen', 'curl' or
6875
- * 'sockets'.
6876
- * @param array $default_args {
6877
- * Parameters of the POST request.
6878
- *
6879
- * @type string $url Destination URL.
6880
- * @type array $params The POST parameters.
6881
- * @type bool $verifypeer True if peer needs to be verified.
6882
- * @type bool $internal_request True if this is an internal
6883
- * request (sent back to the website).
6884
- * @type int $timeout The request timeout in seconds.
6885
- * }
6886
- */
6887
- $options = apply_filters("_wfu_post_request_options", $options, "curl", $default_args);
6888
- curl_setopt_array($ch, $options);
6889
- $result = curl_exec($ch);
6890
- curl_close ($ch);
6891
- return $result;
6892
- }
6893
- elseif ( isset($plugin_options['postmethod']) && $plugin_options['postmethod'] == 'socket' ) {
6894
- // POST request using sockets
6895
- $scheme = "";
6896
- $port = 80;
6897
- $errno = 0;
6898
- $errstr = '';
6899
- $ret = '';
6900
- $url_parts = parse_url($url);
6901
- $host = $url_parts['host'];
6902
- $socket_host = $host;
6903
- $path = $url_parts['path'];
6904
- if ( $url_parts['scheme'] == 'https' ) {
6905
- $scheme = "ssl://";
6906
- $port = 443;
6907
- if ( $timeout == 0 ) $timeout = 30;
6908
- }
6909
- elseif ( $url['scheme'] != 'http' ) return '';
6910
- //configure sockets request for proxy
6911
- if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
6912
- $scheme = "";
6913
- $socket_host = $proxy->host();
6914
- $port = $proxy->port();
6915
- $path = $url;
6916
- }
6917
- if ( $verifypeer ) $handle = fsockopen($scheme.$socket_host, $port, $errno, $errstr, ($timeout == 0 ? ini_get("default_socket_timeout") : $timeout));
6918
- else {
6919
- $context = stream_context_create(array(
6920
- 'ssl' => array(
6921
- 'verify_peer' => false,
6922
- 'verify_peer_name' => false
6923
- )));
6924
- $handle = stream_socket_client($scheme.$socket_host.":".$port, $errno, $errstr, ($timeout == 0 ? ini_get("default_socket_timeout") : $timeout), STREAM_CLIENT_CONNECT, $context);
6925
- }
6926
- if ( $errno !== 0 || $errstr !== '' ) $handle = false;
6927
- if ( $handle !== false ) {
6928
- $content = http_build_query($params);
6929
- $request = "POST " . $path . " HTTP/1.1\r\n";
6930
- $request .= "Host: " . $host . "\r\n";
6931
- $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
6932
- //for internal requests to /wp-admin area that is password protected
6933
- //authorization is required
6934
- if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" )
6935
- $request .= "Authorization: Basic ".base64_encode(WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD"))."\r\n";
6936
- //add proxy authentication if exists and is required
6937
- if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) && $proxy->use_authentication() )
6938
- $request .= $proxy->authentication_header()."\r\n";
6939
- $request .= "Content-length: " . strlen($content) . "\r\n";
6940
- $request .= "Connection: close\r\n\r\n";
6941
- $request .= $content . "\r\n\r\n";
6942
- /** This filter is explained above. */
6943
- $request = apply_filters("_wfu_post_request_options", $request, "socket", $default_args);
6944
- fwrite($handle, $request, strlen($request));
6945
- $response = '';
6946
- while ( !feof($handle) ) {
6947
- $response .= fgets($handle, 4096);
6948
- }
6949
- fclose($handle);
6950
- $ret = wfu_decode_socket_response($response);
6951
- }
6952
- return $ret;
6953
- }
6954
- else {
6955
- // POST request using file_get_contents
6956
- if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
6957
- $url = preg_replace("/^(http|https):\/\//", "$1://".WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD")."@", $url);
6958
- }
6959
- $peer_key = version_compare(PHP_VERSION, '5.6.0', '<') ? 'CN_name' : 'peer_name';
6960
- $http_array = array(
6961
- 'method' => 'POST',
6962
- 'header' => "Content-type: application/x-www-form-urlencoded\r\n",
6963
- 'content' => http_build_query($params)
6964
- );
6965
- //configure fopen request for proxy
6966
- if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
6967
- $http_array['proxy'] = 'tcp://'.$proxy->host().":".$proxy->port();
6968
- if ( $proxy->use_authentication() )
6969
- $http_array['header'] .= $proxy->authentication_header()."\r\n";
6970
- }
6971
- if ( $timeout > 0 ) $http_array['timeout'] = $timeout;
6972
- //for internal requests to /wp-admin area that is password protected
6973
- //authorization is required
6974
- if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
6975
- $http_array['header'] .= "Authorization: Basic ".base64_encode(WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD"))."\r\n";
6976
- }
6977
- $context_params = array( 'http' => $http_array );
6978
- if ( !$verifypeer ) $context_params['ssl'] = array( 'verify_peer' => false, 'allow_self_signed' => true, 'verify_peer_name' => false );
6979
- /** This filter is explained above. */
6980
- $context_params = apply_filters("_wfu_post_request_options", $context_params, "fopen", $default_args);
6981
- $context = stream_context_create($context_params);
6982
- return file_get_contents($url, false, $context);
6983
- }
6984
- }
6985
-
6986
- /**
6987
- * Send GET Request.
6988
- *
6989
- * This function sends a GET request using the method defined in Post Method
6990
- * option of the plugin's Settings. It is noted that the get request is
6991
- * executed synchronously. The function will wait for the response and then it
6992
- * will finish.
6993
- *
6994
- * @since 4.13.0
6995
- *
6996
- * @param string $url The destination URL of the request.
6997
- * @param array $params Optional. Parameters to pass to the GET request.
6998
- * @param bool $verifypeer Optional. Verify the peer for secure (SSL) requests.
6999
- * @param bool $internal_request Optional. True if this is an internal request
7000
- * to targetting /wp-admin area. In this case a username/password will
7001
- * also be passed to the request if Dashboard is password protected.
7002
- * @param int $timeout Optional. Timeout of the request in seconds.
7003
- *
7004
- * @return string The response of the GET request.
7005
- */
7006
- function wfu_get_request($url, $params = array(), $verifypeer = true, $internal_request = false, $timeout = 0) {
7007
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
7008
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
7009
- $default_args = array(
7010
- 'url' => $url,
7011
- 'params' => $params,
7012
- 'verifypeer' => $verifypeer,
7013
- 'internal_request' => $internal_request,
7014
- 'timeout' => $timeout
7015
- );
7016
- $http_params = http_build_query($params);
7017
- $url .= ( $http_params == "" ? "" : "?".$http_params );
7018
- //check proxy
7019
- $proxy = new WP_HTTP_Proxy();
7020
- if ( isset($plugin_options['postmethod']) && $plugin_options['postmethod'] == 'curl' ) {
7021
- // GET request using CURL
7022
- $ch = curl_init($url);
7023
- $options = array(
7024
- CURLINFO_HEADER_OUT => false,
7025
- CURLOPT_HEADER => false,
7026
- CURLOPT_RETURNTRANSFER => true,
7027
- CURLOPT_SSL_VERIFYPEER => $verifypeer,
7028
- CURLOPT_SSL_VERIFYHOST => ( $verifypeer ? CURLOPT_SSL_VERIFYHOST : false )
7029
- );
7030
- if ( $timeout > 0 ) $options[CURLOPT_TIMEOUT] = $timeout;
7031
- //for internal requests to /wp-admin area that is password protected
7032
- //authorization is required
7033
- if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
7034
- $options[CURLOPT_HTTPAUTH] = CURLAUTH_ANY;
7035
- $options[CURLOPT_USERPWD] = WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD");
7036
- }
7037
- if ( WFU_VAR("WFU_RELAX_CURL_VERIFY_HOST") == "true" ) $options[CURLOPT_SSL_VERIFYHOST] = false;
7038
- //configure cURL request for proxy
7039
- if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
7040
- $options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
7041
- $options[CURLOPT_PROXY] = $proxy->host().":".$proxy->port();
7042
- if ( $proxy->use_authentication() ) {
7043
- $options[CURLOPT_PROXYAUTH] = CURLAUTH_ANY;
7044
- $options[CURLOPT_PROXYUSERPWD] = $proxy->authentication();
7045
- }
7046
- }
7047
- /**
7048
- * Customize GET Request Options.
7049
- *
7050
- * This filter allows custom actions to modify the GET request options
7051
- * before the request is sent.
7052
- *
7053
- * @since 4.13.0
7054
- *
7055
- * @param array $options|string An array of GET options or request
7056
- * string.
7057
- * @param string $method The GET method. It can be 'fopen', 'curl' or
7058
- * 'sockets'.
7059
- * @param array $default_args {
7060
- * Parameters of the GET request.
7061
- *
7062
- * @type string $url Destination URL.
7063
- * @type array $params The GET parameters.
7064
- * @type bool $verifypeer True if peer needs to be verified.
7065
- * @type bool $internal_request True if this is an internal
7066
- * request (sent back to the website).
7067
- * @type int $timeout The request timeout in seconds.
7068
- * }
7069
- */
7070
- $options = apply_filters("_wfu_get_request_options", $options, "curl", $default_args);
7071
- curl_setopt_array($ch, $options);
7072
- $result = curl_exec($ch);
7073
- curl_close ($ch);
7074
- return $result;
7075
- }
7076
- elseif ( isset($plugin_options['postmethod']) && $plugin_options['postmethod'] == 'socket' ) {
7077
- // GET request using sockets
7078
- $scheme = "";
7079
- $port = 80;
7080
- $errno = 0;
7081
- $errstr = '';
7082
- $ret = '';
7083
- $url_parts = parse_url($url);
7084
- $host = $url_parts['host'];
7085
- $socket_host = $host;
7086
- $path = $url_parts['path'];
7087
- if ( $url_parts['scheme'] == 'https' ) {
7088
- $scheme = "ssl://";
7089
- $port = 443;
7090
- if ( $timeout == 0 ) $timeout = 30;
7091
- }
7092
- elseif ( $url['scheme'] != 'http' ) return '';
7093
- //configure sockets request for proxy
7094
- if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
7095
- $scheme = "";
7096
- $socket_host = $proxy->host();
7097
- $port = $proxy->port();
7098
- $path = $url;
7099
- }
7100
- if ( $verifypeer ) $handle = fsockopen($scheme.$socket_host, $port, $errno, $errstr, ($timeout == 0 ? ini_get("default_socket_timeout") : $timeout));
7101
- else {
7102
- $context = stream_context_create(array(
7103
- 'ssl' => array(
7104
- 'verify_peer' => false,
7105
- 'verify_peer_name' => false
7106
- )));
7107
- $handle = stream_socket_client($scheme.$socket_host.":".$port, $errno, $errstr, ($timeout == 0 ? ini_get("default_socket_timeout") : $timeout), STREAM_CLIENT_CONNECT, $context);
7108
- }
7109
- if ( $errno !== 0 || $errstr !== '' ) $handle = false;
7110
- if ( $handle !== false ) {
7111
- $request = "GET " . $path . " HTTP/1.1\r\n";
7112
- $request .= "Host: " . $host . "\r\n";
7113
- //for internal requests to /wp-admin area that is password protected
7114
- //authorization is required
7115
- if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" )
7116
- $request .= "Authorization: Basic ".base64_encode(WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD"))."\r\n";
7117
- //add proxy authentication if exists and is required
7118
- if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) && $proxy->use_authentication() )
7119
- $request .= $proxy->authentication_header()."\r\n";
7120
- $request .= "Connection: close\r\n\r\n";
7121
- $request .= $content . "\r\n\r\n";
7122
- /** This filter is explained above. */
7123
- $request = apply_filters("_wfu_get_request_options", $request, "socket", $default_args);
7124
- fwrite($handle, $request, strlen($request));
7125
- $response = '';
7126
- while ( !feof($handle) ) {
7127
- $response .= fgets($handle, 4096);
7128
- }
7129
- fclose($handle);
7130
- $ret = wfu_decode_socket_response($response);
7131
- }
7132
- return $ret;
7133
- }
7134
- else {
7135
- // GET request using file_get_contents
7136
- if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
7137
- $url = preg_replace("/^(http|https):\/\//", "$1://".WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD")."@", $url);
7138
- }
7139
- $peer_key = version_compare(PHP_VERSION, '5.6.0', '<') ? 'CN_name' : 'peer_name';
7140
- $http_array = array(
7141
- 'method' => 'GET'
7142
- );
7143
- //configure fopen request for proxy
7144
- if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
7145
- $http_array['proxy'] = 'tcp://'.$proxy->host().":".$proxy->port();
7146
- if ( $proxy->use_authentication() )
7147
- $http_array['header'] .= $proxy->authentication_header()."\r\n";
7148
- }
7149
- if ( $timeout > 0 ) $http_array['timeout'] = $timeout;
7150
- //for internal requests to /wp-admin area that is password protected
7151
- //authorization is required
7152
- if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
7153
- $http_array['header'] .= "Authorization: Basic ".base64_encode(WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD"))."\r\n";
7154
- }
7155
- $context_params = array( 'http' => $http_array );
7156
- if ( !$verifypeer ) $context_params['ssl'] = array( 'verify_peer' => false, 'allow_self_signed' => true, 'verify_peer_name' => false );
7157
- /** This filter is explained above. */
7158
- $context_params = apply_filters("_wfu_get_request_options", $context_params, "fopen", $default_args);
7159
- $context = stream_context_create($context_params);
7160
- return file_get_contents($url, false, $context);
7161
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7162
  }
1
+ <?php
2
+
3
+ /**
4
+ * General Use Functions of Plugin
5
+ *
6
+ * This file contains general use functions of the plugin.
7
+ *
8
+ * @link /lib/wfu_functions.php
9
+ *
10
+ * @package WordPress File Upload Plugin
11
+ * @subpackage Core Components
12
+ * @since 2.1.2
13
+ */
14
+
15
+ //********************* Debug Functions ****************************************
16
+
17
+ /**
18
+ * Hook on plugin's functions.
19
+ *
20
+ * This is a very powerful function that enables almost all plugin functions to
21
+ * be redeclared, either in whole or partially. Here is what it can do:
22
+ *
23
+ * - It can execute a hook, based on the function parameters and then
24
+ * execute the original function.
25
+ * - It can execute a hook, based on the function's parameters and then
26
+ * return without executing the original function. This mode is like
27
+ * entirely redeclaring the original function.
28
+ * - It can execute a hook after execution of the original function.
29
+ * - It can redeclare the function parameters or pass new variables to the
30
+ * original function.
31
+ *
32
+ * In order to make a function redeclarable we just need to put the
33
+ * following 'magic' code at the top of its function block:
34
+ *
35
+ * $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out);
36
+ * if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v;
37
+ * switch($a) { case 'R': return $out['output']; break; case 'D':
38
+ * die($out['output']); }
39
+ *
40
+ * Then the function can be hooked through the filter wfu_debug-{__FUNCTION__}.
41
+ *
42
+ * The hook function takes the same parameters as the original function, plus
43
+ * one, which comes first and determines the behaviour of the hook function.
44
+ *
45
+ * This parameter is an array having three items as follows:
46
+ *
47
+ * - item 'output' contains the output of the original function (if exists)
48
+ * - item 'result' has no meaning as input parameter but as returning one
49
+ * - item 'vars' has no meaning as input parameter but as returning one
50
+ *
51
+ * The hook function must return the same array as follows:
52
+ *
53
+ * - item 'output' must contain the hook's output
54
+ * - item 'result' must be either 'X', 'R', or 'D' when the hook is executed
55
+ * at the beginning of the function, as explained below. It determines how
56
+ * the hook will be handled, as follows:
57
+ * - If 'result' is 'X' then the result of the hook function will be
58
+ * ignored and the original function will be executed afterwards.
59
+ * - If 'result' is 'R' then the original function will terminate
60
+ * returning the output of the hook function. So it is like having been
61
+ * entirely substituted by the hook function.
62
+ * - If 'result' is 'D' then the original function will die returning the
63
+ * output of the hook function. This applies to ajax handlers.
64
+ * In the case that the hook is executed at the end of the function, then
65
+ * item 'result' must always be 'R'.
66
+ * - item 'vars' is an associative array that contains any variables that the
67
+ * hook wants to pass to the original function like this:
68
+ * $res['output'] = array('varname1' => value1, 'varname2' => value2);
69
+ * Item 'vars' can be used to redeclare the function arguments and it is a
70
+ * workaround to handling arguments passed by reference.
71
+ *
72
+ * It is noted that the hook can be executed either before or after execution
73
+ * of the original function, despite the fact that the 'magic' code is added
74
+ * to the beginning of the function.
75
+ *
76
+ * - To execute the hook before the function a global variable with name
77
+ * wfu_debug-{__FUNCTION__} must be declared.
78
+ * - To execute the hook after the function a global variable with name
79
+ * wfu_debug_end-{__FUNCTION__} must be declared.
80
+ *
81
+ * It is noted that if both of these global variables are declared, or none of
82
+ * them then the hook will not work.
83
+ *
84
+ * Arguments passed by reference: When declaring the hook filter, all arguments
85
+ * are passed by value, even if some of the original function's arguments pass
86
+ * by reference. However no PHP warnings and errors will be generated due to
87
+ * this difference. If the hook wants to change the value of an argument and
88
+ * reflect this change to the original function, it is possible through item
89
+ * 'vars' explained above. For example, if the original function passes
90
+ * argument $var1 by reference (it is declared as &$var1 in the function
91
+ * parameters), we cannot use the syntax $var1 = ...; inside the hook filter
92
+ * but we can use the syntax $res['vars']['var1'] = ...; and this will result
93
+ * $var1 in the original function to get the new value!
94
+ *
95
+ * @since 3.11.0
96
+ *
97
+ * @param string $function The function name of the original function.
98
+ * @param array $args An array of parameters of the original function.
99
+ * @param string $out Tt stores the output of the hook function.
100
+ *
101
+ * @return string Returns how the hook function will be handled ('X': hook
102
+ * output must be ignored, 'R': the original function must return the
103
+ * hook's output, 'D': the original function must die returning the
104
+ * hook's output).
105
+ */
106
+ function WFU_FUNCTION_HOOK($function, $args, &$out) {
107
+ // exit if plugin's debug mode is off or the hook has not been declared in
108
+ // global variables;
109
+ if ( WFU_VAR("WFU_DEBUG") != "ON" || !( isset($GLOBALS["wfu_debug-".$function]) xor isset($GLOBALS["wfu_debug_end-".$function]) ) ) return 'X';
110
+ // exit if function name is empty or invalid
111
+ if ( $function == "" || preg_replace("/[^0-9a-zA-Z_]/", "", $function) != $function ) return 'X';
112
+ //if the hook has been declared in global variables with wfu_debug_end-
113
+ //prefix then it will run at the end of the function
114
+ if ( isset($GLOBALS["wfu_debug_end-".$function]) ) {
115
+ $args_count = count($args);
116
+ //if a flag (specific string) is contained in the last position of the
117
+ //arguments list then do not re-execute the hook as this is the second
118
+ //pass
119
+ if ( $args_count > 0 && $args[$args_count - 1] === "wfu_debug_end-".$function."-second_pass" ) return 'X';
120
+ else {
121
+ //create an array of references to the function arguments and pass
122
+ //this to call_user_func_array instead of $args; this is a
123
+ //workaround to avoid PHP warnings when the original function passes
124
+ //arguments by reference
125
+ $args_byref = array();
126
+ foreach ( $args as $key => &$arg ) $args_byref[$key] = &$arg;
127
+ //add a flag (specific string) as the last argument in order to
128
+ //denote that the next execution of the hook is the second pass
129
+ array_push($args_byref, "wfu_debug_end-".$function."-second_pass");
130
+ //call the original function and get the returned value; it will
131
+ //contain the flag in the arguments, so the hook will not be
132
+ //executed again and the whole script will not be put in an infinite
133
+ //loop
134
+ $ret = call_user_func_array($function, $args_byref);
135
+ //pass the original function's output to the hook
136
+ array_splice($args, 0, 0, array( array( "output" => $ret, "result" => "X", "vars" => array() ) ));
137
+ /**
138
+ * Hook on a Specific Function.
139
+ *
140
+ * This filter allows to redeclare, or change the behaviour, of the
141
+ * original function $function.
142
+ *
143
+ * @since 3.11.0
144
+ *
145
+ * @param array $args Array of parameters of the original function.
146
+ */
147
+ $res = apply_filters_ref_array("wfu_debug-".$function, $args);
148
+ if ( !is_array($res) || !isset($res["output"]) || !isset($res["result"]) ) $res = array( "output" => $ret, "result" => "R" );
149
+ if ( $res["result"] != 'R' ) $res["result"] = 'R';
150
+ if ( isset($res["vars"]) && !is_array($res["vars"]) ) $res["vars"] = array();
151
+ $out = $res;
152
+ return $res["result"];
153
+ }
154
+ }
155
+ else {
156
+ // prepare the arguments for the hook
157
+ array_splice($args, 0, 0, array( array( "output" => "", "result" => "X", "vars" => array() ) ));
158
+ /** This hook is decribed above. */
159
+ $res = apply_filters_ref_array("wfu_debug-".$function, $args);
160
+ // exit if $res is invalid
161
+ if ( !is_array($res) || !isset($res["output"]) || !isset($res["result"]) ) $res = array( "output" => "", "result" => "X" );
162
+ if ( $res["result"] != 'X' && $res["result"] != 'R' && $res["result"] != 'D' ) $res["result"] = 'X';
163
+ if ( isset($res["vars"]) && !is_array($res["vars"]) ) $res["vars"] = array();
164
+ $out = $res;
165
+ // if result is 'X' then the caller must ignore the hook
166
+ // if result is 'R' then the caller must return the hook's output
167
+ // if result is 'D' then the caller must die returning the hook's output
168
+ return $res["result"];
169
+ }
170
+ }
171
+
172
+ //********************* String Functions ***************************************
173
+
174
+ /**
175
+ * Sanitize Filename.
176
+ *
177
+ * This function sanitizes filename so that it is compatible with most file
178
+ * systems. Invalid non-latin characters will be converted into dashes.
179
+ *
180
+ * @since 2.1.2
181
+ *
182
+ * @param string $filename The file name.
183
+ *
184
+ * @return string The sanitized file name.
185
+ */
186
+ function wfu_upload_plugin_clean($filename) {
187
+ $clean = sanitize_file_name($filename);
188
+ if ( WFU_VAR("WFU_SANITIZE_FILENAME_MODE") != "loose" ) {
189
+ $name = wfu_filename($clean);
190
+ $ext = wfu_fileext($clean);
191
+ if ( WFU_VAR("WFU_SANITIZE_FILENAME_DOTS") == "true" ) $name_search = array ( '@[^a-zA-Z0-9_]@' );
192
+ else $name_search = array ( '@[^a-zA-Z0-9._]@' );
193
+ $ext_search = array ( '@[^a-zA-Z0-9._]@' );
194
+ $replace = array ( '-' );
195
+ $clean_name = preg_replace($name_search, $replace, remove_accents($name));
196
+ $clean_ext = preg_replace($ext_search, $replace, remove_accents($ext));
197
+ $clean = $clean_name.".".$clean_ext;
198
+ }
199
+
200
+ return $clean;
201
+ }
202
+
203
+ /**
204
+ * Wildcard Conversion Callback.
205
+ *
206
+ * This function is a callback used in a preg_replace_callback() function to
207
+ * convert wildcard syntax to natural expression.
208
+ *
209
+ * @since 3.9.0
210
+ *
211
+ * @global array $wfu_preg_replace_callback_var An array with matches.
212
+ *
213
+ * @param array $matches An array of matches of preg_replace_callback().
214
+ *
215
+ * @return string The result of the callback processing the matches.
216
+ */
217
+ function _wildcard_to_preg_preg_replace_callback($matches) {
218
+ global $wfu_preg_replace_callback_var;
219
+ array_push($wfu_preg_replace_callback_var, $matches[0]);
220
+ $key = count($wfu_preg_replace_callback_var) - 1;
221
+ return "[".$key."]";
222
+ }
223
+
224
+ /**
225
+ * Wildcard To Natural Expression Conversion.
226
+ *
227
+ * This function converts wildcard syntax of a pattern to natural expression.
228
+ *
229
+ * @since 2.1.2
230
+ *
231
+ * @global array $wfu_preg_replace_callback_var An array with matches.
232
+ *
233
+ * @param string $pattern The pattern to convert.
234
+ * @param bool $strict Optional. Strict matching. If true, dot symbols (.) will
235
+ * not be matched.
236
+ *
237
+ * @return The converted natural expression pattern.
238
+ */
239
+ function wfu_upload_plugin_wildcard_to_preg($pattern, $strict = false) {
240
+ global $wfu_preg_replace_callback_var;
241
+ $wfu_preg_replace_callback_var = array();
242
+ $pattern = preg_replace_callback("/\[(.*?)\]/", "_wildcard_to_preg_preg_replace_callback", $pattern);
243
+ if ( !$strict ) $pattern = '/^' . str_replace(array('\*', '\?', '\[', '\]'), array('.*', '.', '[', ']'), preg_quote($pattern)) . '$/is';
244
+ else $pattern = '/^' . str_replace(array('\*', '\?', '\[', '\]'), array('[^.]*', '.', '[', ']'), preg_quote($pattern)) . '$/is';
245
+ foreach ($wfu_preg_replace_callback_var as $key => $match)
246
+ $pattern = str_replace("[".$key."]", $match, $pattern);
247
+ return $pattern;
248
+ }
249
+
250
+ /**
251
+ * Wildcard To MySQL Natural Expression Conversion.
252
+ *
253
+ * This function converts wildcard syntax of a pattern to MySQL natural
254
+ * expression.
255
+ *
256
+ * @since 3.2.1
257
+ *
258
+ * @redeclarable
259
+ *
260
+ * @param string $pattern The pattern to convert.
261
+ *
262
+ * @return The converted MySQL natural expression pattern.
263
+ */
264
+ function wfu_upload_plugin_wildcard_to_mysqlregexp($pattern) {
265
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
266
+ if ( substr($pattern, 0, 6) == "regex:" ) return str_replace("\\", "\\\\", substr($pattern, 6));
267
+ else return str_replace("\\", "\\\\", '^'.str_replace(array('\*', '\?', '\[', '\]'), array('.*', '.', '[', ']'), preg_quote($pattern)).'$');
268
+ }
269
+
270
+ /**
271
+ * Match String With Pattern.
272
+ *
273
+ * This function checks if a specific string matches with a pattern.
274
+ *
275
+ * @since 2.1.2
276
+ *
277
+ * @param string $pattern The pattern to match.
278
+ * @param string $str The string to match.
279
+ * @param bool $strict Defines whether strict mode will be used. In strict mode
280
+ * dot symbols (.) are not considered as normal characters and are not
281
+ * matched with preg * symbol.
282
+ *
283
+ * @return bool True if there is a match, false otherwise.
284
+ */
285
+ function wfu_upload_plugin_wildcard_match($pattern, $str, $strict = false) {
286
+ $pattern = wfu_upload_plugin_wildcard_to_preg($pattern, $strict);
287
+ return preg_match($pattern, $str);
288
+ }
289
+
290
+ /**
291
+ * Convert String to Hex.
292
+ *
293
+ * This function converts every character of a string into a 2-byte hex
294
+ * representation.
295
+ *
296
+ * @since 2.1.2
297
+ *
298
+ * @param string $string The string to convert.
299
+ *
300
+ * @return string The converted hex string.
301
+ */
302
+ function wfu_plugin_encode_string($string) {
303
+ $array = unpack('H*', $string);
304
+ return $array[1];
305
+
306
+ $array = unpack('C*', $string);
307
+ $new_string = "";
308
+ for ($i = 1; $i <= count($array); $i ++) {
309
+ $new_string .= sprintf("%02X", $array[$i]);
310
+ }
311
+ return $new_string;
312
+ }
313
+
314
+ /**
315
+ * Convert Hex to String.
316
+ *
317
+ * This function converts a hex string into a normal ASCII string.
318
+ *
319
+ * @since 2.1.2
320
+ *
321
+ * @param string $string The hex string to convert.
322
+ *
323
+ * @return string The converted ASCII string.
324
+ */
325
+ function wfu_plugin_decode_string($string) {
326
+ return pack('H*', $string);
327
+
328
+ $new_string = "";
329
+ for ($i = 0; $i < strlen($string); $i += 2 ) {
330
+ $new_string .= sprintf("%c", hexdec(substr($string, $i ,2)));
331
+ }
332
+ return $new_string;
333
+ }
334
+
335
+ /**
336
+ * Create a Random String.
337
+ *
338
+ * This function creates a random string composing of latin letters and numbers.
339
+ *
340
+ * @since 2.1.2
341
+ *
342
+ * @param integer $len The length of the string.
343
+ * @param bool $hex True if a hex string must be generated.
344
+ *
345
+ * @return string The random string.
346
+ */
347
+ function wfu_create_random_string($len, $hex = false) {
348
+ $base1 = 'ABCDEFGHKLMNOPQRSTWXYZabcdefghjkmnpqrstwxyz123456789';
349
+ $base2 = 'ABCDEFGHKLMNOPQRSTWXYZabcdefghjkmnpqrstwxyz123456789';
350
+ if ( $hex ) {
351
+ $base1 = 'abcdef123456789';
352
+ $base2 = 'abcdef0123456789';
353
+ }
354
+ $max1 = strlen($base1) - 1;
355
+ $max2 = strlen($base2) - 1;
356
+ $activatecode = '';
357
+ if ( WFU_VAR("WFU_ALTERNATIVE_RANDOMIZER") != "true" )
358
+ mt_srand((double)microtime()*1000000);
359
+ else mt_srand((double)substr(uniqid("", true), 15));
360
+ $is_first = true;
361
+ while (strlen($activatecode) < $len) {
362
+ if ( $is_first ) {
363
+ $activatecode .= $base1[mt_rand(0, $max1)];
364
+ $is_first = false;
365
+ }
366
+ else $activatecode .= $base2[mt_rand(0, $max2)];
367
+ }
368
+ return $activatecode;
369
+ }
370
+
371
+ /**
372
+ * Join Two or More Strings.
373
+ *
374
+ * This function joins one or more strings. The strings are passed in the
375
+ * function as 2nd, 3rd, 4rth and so on parameters.
376
+ *
377
+ * @since 2.1.2
378
+ *
379
+ * @param string $delimeter The delimeter to use to join the strings.
380
+ *
381
+ * @return string The resulted joined string.
382
+ */
383
+ function wfu_join_strings($delimeter) {
384
+ $arr = func_get_args();
385
+ unset($arr[0]);
386
+ foreach ($arr as $key => $item)
387
+ if ( $item == "" ) unset($arr[$key]);
388
+ return join($delimeter, $arr);
389
+ }
390
+
391
+ /**
392
+ * Create a String of Zeros.
393
+ *
394
+ * This function creates a string filled with zeros. It is designed to be fast
395
+ * even when the length of the string is large.
396
+ *
397
+ * @since 2.1.2
398
+ *
399
+ * @param integer $size The size of the string.
400
+ *
401
+ * @return string The resulted string.
402
+ */
403
+ function wfu_create_string($size) {
404
+ $piece = str_repeat("0", 1024);
405
+ $str = "";
406
+ $reps = $size / 1024;
407
+ $rem = $size - 1024 * $reps;
408
+ for ( $i = 0; $i < $reps; $i++ ) $str .= $piece;
409
+ $str .= substr($piece, 0, $rem);
410
+ return $str;
411
+ }
412
+
413
+ /**
414
+ * Prepare String for HTML Output.
415
+ *
416
+ * This function converts newline characters into <br> tags and tabs/spaces into
417
+ * &nbsp; entities, so that they can be property shown in HTML output.
418
+ *
419
+ * @since 2.7.1
420
+ *
421
+ * @param string $output The string to be sent to output.
422
+ *
423
+ * @return string The converted HTML ready string.
424
+ */
425
+ function wfu_html_output($output) {
426
+ $output = str_replace(array("\r\n", "\r", "\n"), "<br/>", $output);
427
+ return str_replace(array("\t", " "), "&nbsp;", $output);
428
+ }
429
+
430
+ /**
431
+ * Sanitize a Code.
432
+ *
433
+ * This function sanitizes a code. A code must only contain latin letters and
434
+ * numbers.
435
+ *
436
+ * @since 3.0.0
437
+ *
438
+ * @param string $code The code to sanitize.
439
+ *
440
+ * @return string The sanitized code.
441
+ */
442
+ function wfu_sanitize_code($code) {
443
+ return preg_replace("/[^A-Za-z0-9]/", "", $code);
444
+ }
445
+
446
+ /**
447
+ * Sanitize a Filter.
448
+ *
449
+ * This function sanitizes a filter. A filter must only contain latin letters,
450
+ * numbers and pipe (|).
451
+ *
452
+ * @since 4.16.0
453
+ *
454
+ * @param string $filter The filter to sanitize.
455
+ *
456
+ * @return string The sanitized filter.
457
+ */
458
+ function wfu_sanitize_filter($filter) {
459
+ return preg_replace("/[^A-Za-z0-9|]/", "", $filter);
460
+ }
461
+
462
+ /**
463
+ * Sanitize an Integer.
464
+ *
465
+ * This function sanitizes an integer (passed as string). An integer must only
466
+ * contain numbers, plus (+) and minus (-) symbols.
467
+ *
468
+ * @since 3.1.0
469
+ *
470
+ * @param string $code The integer to sanitize passed as string.
471
+ *
472
+ * @return string The sanitized integer returned as string.
473
+ */
474
+ function wfu_sanitize_int($code) {
475
+ return preg_replace("/[^0-9+\-]/", "", $code);
476
+ }
477
+
478
+ /**
479
+ * Sanitize a Float.
480
+ *
481
+ * This function sanitizes a float (passed as string). A float must only contain
482
+ * numbers, plus (+), minus (-), dot (.) and comma (,) symbols.
483
+ *
484
+ * @since 4.3.3
485
+ *
486
+ * @param string $code The float to sanitize passed as string.
487
+ *
488
+ * @return string The sanitized float returned as string.
489
+ */
490
+ function wfu_sanitize_float($code) {
491
+ return preg_replace("/[^0-9+\-\.,]/", "", $code);
492
+ }
493
+
494
+ /**
495
+ * Sanitize a Color Value.
496
+ *
497
+ * This function sanitizes a color value. A color value must only contain
498
+ * characters a-f or A-F, numbers, number sign (#) and comma (,) symbols.
499
+ *
500
+ * @since 4.3.3
501
+ *
502
+ * @param string $code The color value to sanitize.
503
+ *
504
+ * @return string The sanitized color value.
505
+ */
506
+ function wfu_sanitize_colors($code) {
507
+ return preg_replace("/[^A-Fa-f0-9#,]/", "", $code);
508
+ }
509
+
510
+ /**
511
+ * Sanitize a Tag.
512
+ *
513
+ * This function sanitizes a tag. A tag must only contain latin characters,
514
+ * numbers and underscore (_) symbols.
515
+ *
516
+ * @since 3.1.0
517
+ *
518
+ * @param string $code The tag to sanitize.
519
+ *
520
+ * @return string The sanitized tag.
521
+ */
522
+ function wfu_sanitize_tag($code) {
523
+ return preg_replace("/[^A-Za-z0-9_]/", "", $code);
524
+ }
525
+
526
+ /**
527
+ * Sanitize a Simple JSON Array.
528
+ *
529
+ * This function sanitizes a simple JSON array string. A JSON array string must
530
+ * only contain latin characters, numbers, and symbols _[]",.
531
+ *
532
+ * @since 4.16.0
533
+ *
534
+ * @param string $code The JSON array string to sanitize.
535
+ *
536
+ * @return string The sanitized json array string.
537
+ */
538
+ function wfu_sanitize_jsonarray($arr) {
539
+ return preg_replace("/[^A-Za-z0-9_\[\]\",]/", "", $arr);
540
+ }
541
+
542
+ /**
543
+ * Sanitize a URL.
544
+ *
545
+ * This function sanitizes a URL.
546
+ *
547
+ * @since 3.11.0
548
+ *
549
+ * @param string $url The URL to sanitize.
550
+ *
551
+ * @return string The sanitized URL.
552
+ */
553
+ function wfu_sanitize_url($url) {
554
+ return filter_var(strip_tags($url), FILTER_SANITIZE_URL);
555
+ }
556
+
557
+ /**
558
+ * Sanitize a List of URL.
559
+ *
560
+ * This function sanitizes a list of URLs.
561
+ *
562
+ * @since 3.11.0
563
+ *
564
+ * @param string $urls The URLs to sanitize.
565
+ * @param string $separator The delimeter character of the URLs.
566
+ *
567
+ * @return string The sanitized URLs.
568
+ */
569
+ function wfu_sanitize_urls($urls, $separator) {
570
+ $urls_arr = explode($separator, $urls);
571
+ foreach( $urls_arr as &$url ) $url = wfu_sanitize_url($url);
572
+ return implode($separator, $urls_arr);
573
+ }
574
+
575
+ /**
576
+ * Sanitize a Shortcode.
577
+ *
578
+ * This function sanitizes a shortcode, that is sanitizes all its attributes.
579
+ *
580
+ * @since 4.3.3
581
+ *
582
+ * @param string $shortcode The shortcode to sanitize.
583
+ * @param string $shortcode_tag The shortcode tag.
584
+ *
585
+ * @return string The sanitized shortcode.
586
+ */
587
+ function wfu_sanitize_shortcode($shortcode, $shortcode_tag) {
588
+ $attrs = wfu_shortcode_string_to_array($shortcode);
589
+ $sanitized_attrs = wfu_sanitize_shortcode_array($attrs, $shortcode_tag);
590
+ //reconstruct sanitized shortcode string from array
591
+ $sanitized_shortcode = "";
592
+ foreach ( $sanitized_attrs as $attr => $value )
593
+ $sanitized_shortcode .= ( $sanitized_shortcode == "" ? "" : " " ).$attr.'="'.$value.'"';
594
+
595
+ return $sanitized_shortcode;
596
+ }
597
+
598
+ /**
599
+ * Sanitize Shortcode Attributes.
600
+ *
601
+ * This function sanitizes an array of shortcode attributes.
602
+ *
603
+ * @since 4.5.1
604
+ *
605
+ * @param array $attrs An array of shortcode attributes to sanitize.
606
+ * @param string $shortcode_tag The shortcode tag.
607
+ *
608
+ * @return array The sanitized array of shortcode attributes.
609
+ */
610
+ function wfu_sanitize_shortcode_array($attrs, $shortcode_tag) {
611
+ $sanitized_attrs = array();
612
+ if ( $shortcode_tag == 'wordpress_file_upload' ) $defs = wfu_attribute_definitions();
613
+ else $defs = wfu_browser_attribute_definitions();
614
+ // get validator types for defs
615
+ $def_validators = array();
616
+ foreach ( $defs as $def ) $def_validators[$def['attribute']] = $def['validator'];
617
+ // sanitize each attribute
618
+ foreach ( $attrs as $attr => $value ) {
619
+ //first sanitize the attribute name
620
+ $sanitized = sanitize_text_field($attr);
621
+ //continue only for attributes that sanitization did not crop any
622
+ //characters
623
+ if ( $sanitized == $attr && $attr != "" ) {
624
+ //flatten attributes that have many occurencies
625
+ $flat = preg_replace("/^(.*?)[0-9]*$/", "$1", $attr);
626
+ //get validator type
627
+ $validator = "text";
628
+ if ( isset($def_validators[$flat]) ) $validator = $def_validators[$flat];
629
+ //sanitize value based on validator type
630
+ $new_value = $value;
631
+ switch( $validator ) {
632
+ case "text":
633
+ $new_value = wp_strip_all_tags($value);
634
+ break;
635
+ case "integer":
636
+ $new_value = wfu_sanitize_int($value);
637
+ break;
638
+ case "float":
639
+ $new_value = wfu_sanitize_float($value);
640
+ break;
641
+ case "path":
642
+ $new_value = wp_strip_all_tags($value);
643
+ break;
644
+ case "link":
645
+ $new_value = wp_strip_all_tags($value);
646
+ break;
647
+ case "emailheaders":
648
+ if ( strpos(strtolower($value), "<script") !== false ) $new_value = "";
649
+ break;
650
+ case "emailsubject":
651
+ if ( strpos(strtolower($value), "<script") !== false ) $new_value = "";
652
+ break;
653
+ case "emailbody":
654
+ if ( strpos(strtolower($value), "<script") !== false ) $new_value = "";
655
+ break;
656
+ case "colors":
657
+ $new_value = wfu_sanitize_colors($value);
658
+ break;
659
+ case "css":
660
+ $new_value = wp_strip_all_tags($value);
661
+ break;
662
+ case "datetime":
663
+ $new_value = wp_strip_all_tags($value);
664
+ break;
665
+ case "pattern":
666
+ if ( substr_count($value, "'") > 0 && substr_count($value, "'") > substr_count($value, "\\'") ) $new_value = "";
667
+ break;
668
+ default:
669
+ $new_value = wp_strip_all_tags($value);
670
+ }
671
+ /**
672
+ * Custom Shortcode Sanitization.
673
+ *
674
+ * This filter allows custom actions to change the sanitization
675
+ * result of shortcode attributes.
676
+ *
677
+ * @since 4.3.3
678
+ *
679
+ * @param string $new_value New sanitized value of the attribute.
680
+ * @param string $attr The attribute name.
681
+ * @param string $validator The type of attribute used to determine
682
+ * the type of validator to use.
683
+ * @param string $value The initial value of the attribute.
684
+ */
685
+ $new_value = apply_filters("_wfu_sanitize_shortcode", $new_value, $attr, $validator, $value);
686
+ $sanitized_attrs[$attr] = $new_value;
687
+ }
688
+ }
689
+
690
+ return $sanitized_attrs;
691
+ }
692
+
693
+ /**
694
+ * Escape a Variable.
695
+ *
696
+ * This function escapes (adds backslashes before characters that need to be
697
+ * escaped) a variable, even if it is an array of unlimited depth.
698
+ *
699
+ * @since 3.3.0
700
+ *
701
+ * @param mixed $value The variable to be escaped.
702
+ *
703
+ * @return mixed The escaped variable.
704
+ */
705
+ function wfu_slash( $value ) {
706
+ if ( is_array( $value ) ) {
707
+ foreach ( $value as $k => $v ) {
708
+ if ( is_array( $v ) ) {
709
+ $value[$k] = wfu_slash( $v );
710
+ }
711
+ else {
712
+ $value[$k] = addslashes( $v );
713
+ }
714
+ }
715
+ }
716
+ else {
717
+ $value = addslashes( $value );
718
+ }
719
+
720
+ return $value;
721
+ }
722
+
723
+ /**
724
+ * Generate a Global Short-Life Token.
725
+ *
726
+ * This function generates a short-life token that is stored in Wordpress
727
+ * Options and has a global scope (is accessible by all users).
728
+ *
729
+ * @since 3.5.0
730
+ *
731
+ * @param integer $timeout The life of the token in seconds.
732
+ *
733
+ * @return string The token.
734
+ */
735
+ function wfu_generate_global_short_token($timeout) {
736
+ $token = wfu_create_random_string(16);
737
+ $expire = time() + (int)$timeout;
738
+ update_option('wfu_gst_'.$token, $expire);
739
+ return $token;
740
+ }
741
+
742
+ /**
743
+ * Verify a Global Short-Life Token.
744
+ *
745
+ * This function verifies that a global short-life token exists and it not
746
+ * expired. After verification the token is removed.
747
+ *
748
+ * @since 3.5.0
749
+ *
750
+ * @param string $token The token to verify.
751
+ *
752
+ * @return bool True if verification was successful, false otherwise.
753
+ */
754
+ function wfu_verify_global_short_token($token) {
755
+ $timeout = get_option('wfu_gst_'.$token);
756
+ if ( $timeout === false ) return false;
757
+ delete_option('wfu_gst_'.$token);
758
+ return ( $timeout > time() );
759
+ }
760
+
761
+ /**
762
+ * Generate a User Short-Life Token.
763
+ *
764
+ * This function generates a short-life token that is stored in a user's User
765
+ * Space and has a user scope (is accessible only by this user).
766
+ *
767
+ * @since 4.9.0
768
+ *
769
+ * @param integer $timeout The life of the token in seconds.
770
+ *
771
+ * @return string The token.
772
+ */
773
+ function wfu_generate_user_short_token($timeout) {
774
+ $token = wfu_create_random_string(16);
775
+ $expire = time() + (int)$timeout;
776
+ WFU_USVAR_store('wfu_ust_'.$token, $expire);
777
+ return $token;
778
+ }
779
+
780
+ /**
781
+ * Verify a User Short-Life Token.
782
+ *
783
+ * This function verifies that a user short-life token exists and it not
784
+ * expired. After verification the token is removed.
785
+ *
786
+ * @since 4.9.0
787
+ *
788
+ * @param string $token The token to verify.
789
+ *
790
+ * @return bool True if verification was successful, false otherwise.
791
+ */
792
+ function wfu_verify_user_short_token($token) {
793
+ if ( !WFU_USVAR_exists('wfu_ust_'.$token) ) return false;
794
+ $timeout = WFU_USVAR('wfu_ust_'.$token);
795
+ WFU_USVAR_unset('wfu_ust_'.$token);
796
+ return ( $timeout > time() );
797
+ }
798
+
799
+ //********************* Array Functions ****************************************
800
+
801
+ /**
802
+ * Encode Array to String.
803
+ *
804
+ * This function converts an array to a JSON string and then encodes it to its
805
+ * hex representation.
806
+ *
807
+ * @since 2.1.2
808
+ *
809
+ * @param array $arr The array to encode.
810
+ *
811
+ * @return string The encoded hex string.
812
+ */
813
+ function wfu_encode_array_to_string($arr) {
814
+ $arr_str = json_encode($arr);
815
+ $arr_str = wfu_plugin_encode_string($arr_str);
816
+ return $arr_str;
817
+ }
818
+
819
+ /**
820
+ * Decode Array from String.
821
+ *
822
+ * This function converts a hex string to its ASCII representation, which is a
823
+ * JSON string and then decodes it to an array.
824
+ *
825
+ * @since 2.1.2
826
+ *
827
+ * @param string $arr_str The encoded hex string to decode.
828
+ *
829
+ * @return array The decoded array.
830
+ */
831
+ function wfu_decode_array_from_string($arr_str) {
832
+ $arr_str = wfu_plugin_decode_string($arr_str);
833
+ $arr = json_decode($arr_str, true);
834
+ return $arr;
835
+ }
836
+
837
+ /**
838
+ * Decode HTML Entities in Array.
839
+ *
840
+ * This function decodes HTML entities found in array values into their special
841
+ * characters. It is useful when reading a shortcode array.
842
+ *
843
+ * @since 2.1.2
844
+ *
845
+ * @param array $source The source array.
846
+ *
847
+ * @return array The decoded array.
848
+ */
849
+ function wfu_plugin_parse_array($source) {
850
+ $keys = array_keys($source);
851
+ $new_arr = array();
852
+ for ($i = 0; $i < count($keys); $i ++)
853
+ $new_arr[$keys[$i]] = wp_specialchars_decode($source[$keys[$i]]);
854
+ return $new_arr;
855
+ }
856
+
857
+ /**
858
+ * Encode Special Characters in Array.
859
+ *
860
+ * This function converts special characters found in array values into HTML
861
+ * entities.
862
+ *
863
+ * @since 2.1.2
864
+ *
865
+ * @param array $arr The source array.
866
+ *
867
+ * @return array The encoded array.
868
+ */
869
+ function wfu_safe_array($arr) {
870
+ return array_map("htmlspecialchars", $arr);
871
+ }
872
+
873
+ /**
874
+ * Remove Nulls from Array.
875
+ *
876
+ * This function removes null items from array.
877
+ *
878
+ * @since 2.1.2
879
+ *
880
+ * @param array $arr The source array.
881
+ *
882
+ * @return array The cleaned array.
883
+ */
884
+ function wfu_array_remove_nulls(&$arr) {
885
+ foreach ( $arr as $key => $arri )
886
+ if ( $arri == null )
887
+ array_splice($arr, $key, 1);
888
+ }
889
+
890
+ /**
891
+ * Sanitize a Variable.
892
+ *
893
+ * This function sanitizes (converts special characters into HTML entities) a
894
+ * variable. If the variable is an array it will sanitize all elements
895
+ * recursively regardless of array depth. If the variable is not of an accepted
896
+ * type then its type will be returned.
897
+ *
898
+ * @since 2.4.4
899
+ *
900
+ * @param mixed $var The variable to sanitize.
901
+ *
902
+ * @return mixed The sanitized variable.
903
+ */
904
+ function wfu_sanitize($var) {
905
+ $typ = gettype($var);
906
+ if ( $typ == "boolean" || $typ == "integer" || $typ == "double" || $typ == "resource" || $typ == "NULL" )
907
+ return $var;
908
+ elseif ( $typ == "string" )
909
+ return htmlspecialchars($var);
910
+ elseif ( $typ == "array" || $typ == "object" ) {
911
+ foreach ( $var as &$item ) $item = wfu_sanitize($item);
912
+ return $var;
913
+ }
914
+ else
915
+ return $typ;
916
+ }
917
+
918
+ /**
919
+ * Mask a Shortcode.
920
+ *
921
+ * This function is part of a process to safely parse a shortcode string into an
922
+ * associative array. It replaces all attribute values by tokens, so that it is
923
+ * easier and safer for the process to separate the attributes.
924
+ *
925
+ * @since 2.2.1
926
+ *
927
+ * @param string $contents The shortcode.
928
+ * @param string $token The token that replaces the shortcode attribute values.
929
+ *
930
+ * @return array An array of converted attributes.
931
+ */
932
+ function _wfu_preg_replace_callback_alt($contents, $token) {
933
+ $in_block = false;
934
+ $prev_pos = 0;
935
+ $new_contents = '';
936
+ $ret['items'] = array();
937
+ $ret['tokens'] = array();
938
+ $ii = 0;
939
+ while ( ($pos = strpos($contents, '"', $prev_pos)) !== false ) {
940
+ if ( !$in_block ) {
941
+ $new_contents .= substr($contents, $prev_pos, $pos - $prev_pos + 1);
942
+ $in_block = true;
943
+ }
944
+ else {
945
+ $ret['items'][$ii] = substr($contents, $prev_pos, $pos - $prev_pos);
946
+ $ret['tokens'][$ii] = $token.sprintf('%03d', $ii);
947
+ $new_contents .= $token.sprintf('%03d', $ii).'"';
948
+ $ii ++;
949
+ $in_block = false;
950
+ }
951
+ $prev_pos = $pos + 1;
952
+ }
953
+ if ( $in_block ) {
954
+ $ret['items'][$ii] = substr($contents, $prev_pos);
955
+ $ret['tokens'][$ii] = $token.sprintf('%03d', $ii);
956
+ $new_contents .= $token.sprintf('%03d', $ii).'"';
957
+ }
958
+ else
959
+ $new_contents .= substr($contents, $prev_pos);
960
+ $ret['contents'] = $new_contents;
961
+ return $ret;
962
+ }
963
+
964
+ /**
965
+ * Parse a Shortcode.
966
+ *
967
+ * This function safely parses a shortcode string into an associative array.
968
+ *
969
+ * @since 2.1.3
970
+ *
971
+ * @param string $shortcode The shortcode.
972
+ *
973
+ * @return array The parsed shortcode as an associative array of attributes.
974
+ */
975
+ function wfu_shortcode_string_to_array($shortcode) {
976
+ $i = 0;
977
+ $m1 = array();
978
+ $m2 = array();
979
+ //for some reason preg_replace_callback does not work in all cases, so it has been replaced by a similar custom inline routine
980
+ // $mm = preg_replace_callback('/"([^"]*)"/', function ($matches) use(&$i, &$m1, &$m2) {array_push($m1, $matches[1]); array_push($m2, "attr".$i); return "attr".$i++;}, $shortcode);
981
+ $ret = _wfu_preg_replace_callback_alt($shortcode, "attr");
982
+ $mm = $ret['contents'];
983
+ $m1 = $ret['items'];
984
+ $m2 = $ret['tokens'];
985
+ $arr = explode(" ", $mm);
986
+ $attrs = array();
987
+ foreach ( $arr as $attr ) {
988
+ if ( trim($attr) != "" ) {
989
+ $attr_arr = explode("=", $attr, 2);
990
+ $key = "";
991
+ if ( count($attr_arr) > 0 ) $key = $attr_arr[0];
992
+ $val = "";
993
+ if ( count($attr_arr) > 1 ) $val = $attr_arr[1];
994
+ if ( trim($key) != "" ) $attrs[trim($key)] = str_replace('"', '', $val);
995
+ }
996
+ }
997
+ $attrs2 = str_replace($m2, $m1, $attrs);
998
+ return $attrs2;
999
+ }
1000
+
1001
+ /**
1002
+ * Compare Two Strings in Ascending Order.
1003
+ *
1004
+ * This function returns the comparison result of two strings. It is part of an
1005
+ * array sorting mechanism.
1006
+ *
1007
+ * @since 3.8.5
1008
+ *
1009
+ * @param string $a The first string.
1010
+ * @param string $b The second string.
1011
+ *
1012
+ * @return int Returns < 0 if a is less than b; > 0 if a is greater than b
1013
+ * and 0 if they are equal.
1014
+ */
1015
+ function wfu_array_sort_function_string_asc($a, $b) {
1016
+ return strcmp(strtolower($a), strtolower($b));
1017
+ }
1018
+
1019
+ /**
1020
+ * Compare Two Strings Having a Second Property in Ascending Order.
1021
+ *
1022
+ * This function returns the comparison result of two strings. If the strings
1023
+ * are equal then comparison will be done based on a second property (id0) of
1024
+ * the strings, so that 0 is never returned. It is part of an array sorting
1025
+ * mechanism.
1026
+ *
1027
+ * @since 3.8.5
1028
+ *
1029
+ * @param array $a The first string. It is passed as an array. 'value' item of
1030
+ * the array is the string. 'id0' item is the second property.
1031
+ * @param array $b The second string. It is passed as an array. 'value' item of
1032
+ * the array is the string. 'id0' item is the second property.
1033
+ *
1034
+ * @return int Returns < 0 if a is less than b; > 0 if a is greater.
1035
+ */
1036
+ function wfu_array_sort_function_string_asc_with_id0($a, $b) {
1037
+ $cmp = strcmp(strtolower($a["value"]), strtolower($b["value"]));
1038
+ if ( $cmp == 0 ) $cmp = ( (int)$a["id0"] < (int)$b["id0"] ? -1 : 1 );
1039
+ return $cmp;
1040
+ }
1041
+
1042
+ /**
1043
+ * Compare Two Strings in Descending Order.
1044
+ *
1045
+ * This function returns the negstive of the comparison result of two strings.
1046
+ * It is part of an array sorting mechanism.
1047
+ *
1048
+ * @since 3.8.5
1049
+ *
1050
+ * @param string $a The first string.
1051
+ * @param string $b The second string.
1052
+ *
1053
+ * @return int Returns > 0 if a is less than b; < 0 if a is greater than b
1054
+ * and 0 if they are equal.
1055
+ */
1056
+ function wfu_array_sort_function_string_desc($a, $b) {
1057
+ return -strcmp(strtolower($a), strtolower($b));
1058
+ }
1059
+
1060
+ /**
1061
+ * Compare Two Strings Having a Second Property in Descending Order.
1062
+ *
1063
+ * This function returns the negative of the comparison result of two strings.
1064
+ * If the strings are equal then comparison will be done based on a second
1065
+ * property (id0) of the strings, so that 0 is never returned. It is part of an
1066
+ * array sorting mechanism.
1067
+ *
1068
+ * @since 3.8.5
1069
+ *
1070
+ * @param array $a The first string. It is passed as an array. 'value' item of
1071
+ * the array is the string. 'id0' item is the second property.
1072
+ * @param array $b The second string. It is passed as an array. 'value' item of
1073
+ * the array is the string. 'id0' item is the second property.
1074
+ *
1075
+ * @return int Returns > 0 if a is less than b; < 0 if a is greater.
1076
+ */
1077
+ function wfu_array_sort_function_string_desc_with_id0($a, $b) {
1078
+ $cmp = strcmp(strtolower($a["value"]), strtolower($b["value"]));
1079
+ if ( $cmp == 0 ) $cmp = ( (int)$a["id0"] < (int)$b["id0"] ? -1 : 1 );
1080
+ return -$cmp;
1081
+ }
1082
+
1083
+ /**
1084
+ * Compare Two Numbers in Ascending Order.
1085
+ *
1086
+ * This function returns the comparison result of two numbers. It is part of an
1087
+ * array sorting mechanism.
1088
+ *
1089
+ * @since 3.8.5
1090
+ *
1091
+ * @param int|float|double $a The first number.
1092
+ * @param int|float|double $b The second number.
1093
+ *
1094
+ * @return int Returns -1 if a is less than b; 1 if a is greater than b
1095
+ * and 0 if they are equal.
1096
+ */
1097
+ function wfu_array_sort_function_numeric_asc($a, $b) {
1098
+ $aa = (double)$a;
1099
+ $bb = (double)$b;
1100
+ if ( $aa < $bb ) return -1;
1101
+ elseif ( $aa > $bb ) return 1;
1102
+ else return 0;
1103
+ }
1104
+
1105
+ /**
1106
+ * Compare Two Numbers Having a Second Property in Ascending Order.
1107
+ *
1108
+ * This function returns the comparison result of two numbers. If the numbers
1109
+ * are equal then comparison will be done based on a second property (id0) of
1110
+ * the numbers, so that 0 is never returned. It is part of an array sorting
1111
+ * mechanism.
1112
+ *
1113
+ * @since 3.8.5
1114
+ *
1115
+ * @param array $a The first number. It is passed as an array. 'value' item of
1116
+ * the array is the number. 'id0' item is the second property.
1117
+ * @param array $b The second number. It is passed as an array. 'value' item of
1118
+ * the array is the number. 'id0' item is the second property.
1119
+ *
1120
+ * @return int Returns -1 if a is less than b; 1 if a is greater.
1121
+ */
1122
+ function wfu_array_sort_function_numeric_asc_with_id0($a, $b) {
1123
+ $aa = (double)$a["value"];
1124
+ $bb = (double)$b["value"];
1125
+ if ( $aa < $bb ) return -1;
1126
+ elseif ( $aa > $bb ) return 1;
1127
+ elseif ( (int)$a["id0"] < (int)$b["id0"] ) return -1;
1128
+ else return 1;
1129
+ }
1130
+
1131
+ /**
1132
+ * Compare Two Numbers in Descending Order.
1133
+ *
1134
+ * This function returns the negstive of the comparison result of two numbers.
1135
+ * It is part of an array sorting mechanism.
1136
+ *
1137
+ * @since 3.8.5
1138
+ *
1139
+ * @param int|float|number $a The first number.
1140
+ * @param int|float|number $b The second number.
1141
+ *
1142
+ * @return int Returns 1 if a is less than b; -1 if a is greater than b
1143
+ * and 0 if they are equal.
1144
+ */
1145
+ function wfu_array_sort_function_numeric_desc($a, $b) {
1146
+ $aa = (double)$a;
1147
+ $bb = (double)$b;
1148
+ if ( $aa > $bb ) return -1;
1149
+ elseif ( $aa < $bb ) return 1;
1150
+ else return 0;
1151
+ }
1152
+
1153
+ /**
1154
+ * Compare Two Numbers Having a Second Property in Descending Order.
1155
+ *
1156
+ * This function returns the negative of the comparison result of two numbers.
1157
+ * If the numbers are equal then comparison will be done based on a second
1158
+ * property (id0) of the numbers, so that 0 is never returned. It is part of an
1159
+ * array sorting mechanism.
1160
+ *
1161
+ * @since 3.8.5
1162
+ *
1163
+ * @param array $a The first number. It is passed as an array. 'value' item of
1164
+ * the array is the number. 'id0' item is the second property.
1165
+ * @param array $b The second number. It is passed as an array. 'value' item of
1166
+ * the array is the number. 'id0' item is the second property.
1167
+ *
1168
+ * @return int Returns 1 if a is less than b; -1 if a is greater.
1169
+ */
1170
+ function wfu_array_sort_function_numeric_desc_with_id0($a, $b) {
1171
+ $aa = (double)$a["value"];
1172
+ $bb = (double)$b["value"];
1173
+ if ( $aa > $bb ) return -1;
1174
+ elseif ( $aa < $bb ) return 1;
1175
+ elseif ( (int)$a["id0"] > (int)$b["id0"] ) return -1;
1176
+ else return 1;
1177
+ }
1178
+
1179
+ /**
1180
+ * Sort an Array Based on Key.
1181
+ *
1182
+ * This function sorts an array based on a key. It is used to sort a tabular
1183
+ * list based on a column. Every item of the array is another associative array
1184
+ * representing a row of the table. The key of every item is the column of the
1185
+ * table.
1186
+ *
1187
+ * @since 2.2.1
1188
+ *
1189
+ * @param array $array. The array to sort.
1190
+ * @param string $on. The sorting column name. If it is preceeded by 's:' it
1191
+ * will be sorted as string. If it is preceeded by 'n:' it will be sorted
1192
+ * as numeric.
1193
+ * @param int $order Optional. The sorting order. It can be SORT_ASC or
1194
+ * SORT_DESC.
1195
+ * @param bool $with_id0 Optional. A secord property will be used for sorting.
1196
+ *
1197
+ * @return array The sorted array.
1198
+ */
1199
+ function wfu_array_sort($array, $on, $order = SORT_ASC, $with_id0 = false) {
1200
+ $new_array = array();
1201
+ $sortable_array = array();
1202
+
1203
+ $pos = strpos($on, ":");
1204
+ if ( $pos !== false ) {
1205
+ $sorttype = substr($on, $pos + 1);
1206
+ if ( $sorttype == "" ) $sorttype = "s";
1207
+ $on = substr($on, 0, $pos);
1208
+ }
1209
+ else $sorttype = "s";
1210
+
1211
+ if (count($array) > 0) {
1212
+ foreach ($array as $k => $v) {
1213
+ if (is_array($v)) {
1214
+ foreach ($v as $k2 => $v2) {
1215
+ if ($k2 == $on) {
1216
+ $sortable_array[$k] = ( $with_id0 ? array( "id0" => $v["id0"], "value" => $v2 ) : $v2 );
1217
+ }
1218
+ }
1219
+ } else {
1220
+ $sortable_array[$k] = $v;
1221
+ $with_id0 = false;
1222
+ }
1223
+ }
1224
+
1225
+ uasort($sortable_array, "wfu_array_sort_function_".( $sorttype == "n" ? "numeric" : "string" )."_".( $order == SORT_ASC ? "asc" : "desc" ).( $with_id0 ? "_with_id0" : "" ));
1226
+
1227
+ foreach ($sortable_array as $k => $v) {
1228
+ $new_array[$k] = $array[$k];
1229
+ }
1230
+ }
1231
+
1232
+ return $new_array;
1233
+ }
1234
+
1235
+ /**
1236
+ * Output Array Contents.
1237
+ *
1238
+ * This function echoes array contents to show properly in a front-end page.
1239
+ *
1240
+ * @since 3.4.0
1241
+ *
1242
+ * @param array $arr. The array to echo.
1243
+ */
1244
+ function wfu_echo_array($arr) {
1245
+ if ( !is_array($arr) ) return;
1246
+ echo '<pre>'.print_r($arr, true).'</pre>';
1247
+ }
1248
+
1249
+ /**
1250
+ * Minify Code.
1251
+ *
1252
+ * This function minifies a piece of code. It is used to minify inline code of
1253
+ * the plugin. It supports minification of Javascript or CSS code.
1254
+ *
1255
+ * @since 4.2.0
1256
+ *
1257
+ * @param string $lang. The code language. It can be 'JS' or 'CSS'.
1258
+ * @param string $code. The code to minify.
1259
+ *
1260
+ * @return array An array holding minification result. Item 'result' is true if
1261
+ * minification was successful and false otherwise. Item 'minified_code'
1262
+ * holds the minified code.
1263
+ */
1264
+ function wfu_minify_code($lang, $code) {
1265
+ $ret = array( "result" => false, "minified_code" => "" );
1266
+ $php_version = preg_replace("/-.*/", "", phpversion());
1267
+ $unsupported = false;
1268
+ $ret = wfu_compare_versions($php_version, '5.3.0');
1269
+ $unsupported = ( $ret['status'] && $ret['result'] == 'lower' );
1270
+ if ( !$unsupported ) {
1271
+ $path = ABSWPFILEUPLOAD_DIR;
1272
+ if ( !class_exists('MatthiasMullie\Minify\Minify') ) {
1273
+ include_once $path.'vendor/minifier/minify/src/Minify.php';
1274
+ include_once $path.'vendor/minifier/minify/src/CSS.php';
1275
+ include_once $path.'vendor/minifier/minify/src/JS.php';
1276
+ include_once $path.'vendor/minifier/minify/src/Exception.php';
1277
+ include_once $path.'vendor/minifier/minify/src/Exceptions/BasicException.php';
1278
+ include_once $path.'vendor/minifier/minify/src/Exceptions/FileImportException.php';
1279
+ include_once $path.'vendor/minifier/minify/src/Exceptions/IOException.php';
1280
+ }
1281
+ if ( !class_exists('MatthiasMullie\PathConverter\Converter') ) {
1282
+ include_once $path.'vendor/minifier/path-converter/src/ConverterInterface.php';
1283
+ include_once $path.'vendor/minifier/path-converter/src/Converter.php';
1284
+ }
1285
+ $minifier = null;
1286
+ eval('$minifier = new MatthiasMullie\Minify\\'.strtoupper($lang).'($code);');
1287
+ if ( $minifier !== null ) {
1288
+ $ret["result"] = true;
1289
+ $ret["minified_code"] = $minifier->minify();
1290
+ }
1291
+ }
1292
+
1293
+ return $ret;
1294
+ }
1295
+
1296
+ /**
1297
+ * Prepare CSS Code for Output.
1298
+ *
1299
+ * This function prepares CSS code for HTML output. It minifies the code if
1300
+ * necessary and encloses it in <style> tags.
1301
+ *
1302
+ * @since 4.0.0
1303
+ *
1304
+ * @param string $css. The CSS code to output.
1305
+ *
1306
+ * @return string The resulted HTML code.
1307
+ */
1308
+ function wfu_css_to_HTML($css) {
1309
+ if ( WFU_VAR("WFU_MINIFY_INLINE_CSS") == "true" ) {
1310
+ $ret = wfu_minify_code("CSS", $css);
1311
+ if ( $ret["result"] ) $css = $ret["minified_code"];
1312
+ }
1313
+ $echo_str = "\n\t".'<style>';
1314
+ $echo_str .= "\n".$css;
1315
+ $echo_str .= "\n\t".'</style>';
1316
+
1317
+ return $echo_str;
1318
+ }
1319
+
1320
+ /**
1321
+ * Prepare Javascript Code for Output.
1322
+ *
1323
+ * This function prepares Javascript code for HTML output. It minifies the code
1324
+ * if necessary and encloses it in <script> tags.
1325
+ *
1326
+ * @since 4.0.0
1327
+ *
1328
+ * @param string $js. The Javascript code to output.
1329
+ *
1330
+ * @return string The resulted HTML code.
1331
+ */
1332
+ function wfu_js_to_HTML($js) {
1333
+ if ( WFU_VAR("WFU_MINIFY_INLINE_JS") == "true" ) {
1334
+ $ret = wfu_minify_code("JS", $js);
1335
+ if ( $ret["result"] ) $js = $ret["minified_code"];
1336
+ }
1337
+ $echo_str = '<script type="text/javascript">';
1338
+ $echo_str .= "\n".$js;
1339
+ $echo_str .= "\n".'</script>';
1340
+
1341
+ return $echo_str;
1342
+ }
1343
+
1344
+ /**
1345
+ * Generate Basic Inline Javascript Loader Functions.
1346
+ *
1347
+ * This function returns the initialization code of the basic inline JS loader
1348
+ * functions:
1349
+ *
1350
+ * wfu_js_decode_obj: This JS function generates an object from its string
1351
+ * representation.
1352
+ *
1353
+ * wfu_run_js: This JS function calls other JS functions. It is used to run
1354
+ * inline functions safely. Inline functions use objects, like GlobalData,
1355
+ * which initialize after Javascript files of the plugin have been loaded.
1356
+ * Usually these files are declared at the header of a page and load before
1357
+ * the inline code. So objects like GlobalData have been initialized and
1358
+ * inline functions can run without errors. However sometimes Javascript files
1359
+ * are declared at the footer, or handled by cache plugins and load after the
1360
+ * inline code. In these cases wfu_run_js will not run the inline functions
1361
+ * immediately. It will put them in a JS Bank, so that they run safely after
1362
+ * the Javascript files have been loaded.
1363
+ *
1364
+ * @since 4.2.0
1365
+ *
1366
+ * @return string The HTML code of the inline Javascript loader functions.
1367
+ */
1368
+ function wfu_init_run_js_script() {
1369
+ // $script = 'if (typeof wfu_js_decode_obj == "undefined") function wfu_js_decode_obj(obj_str) { var obj = null; if (obj_str == "window") obj = window; else { var match = obj_str.match(new RegExp(\'GlobalData(\\\\.(WFU|WFUB)\\\\[(.*?)\\\\](\\\\.(.*))?)?$\')); if (match) { obj = GlobalData; if (match[3]) obj = obj[match[2]][match[3]]; if (match[5]) obj = obj[match[5]]; } } return obj; }';
1370
+ $script = 'if (typeof wfu_js_decode_obj == "undefined") function wfu_js_decode_obj(obj_str) { var obj = null; if (obj_str == "window") obj = window; else { var dbs = String.fromCharCode(92); var match = obj_str.match(new RegExp(\'GlobalData(\' + dbs + \'.(WFU|WFUB)\' + dbs + \'[(.*?)\' + dbs + \'](\' + dbs + \'.(.*))?)?$\')); if (match) { obj = GlobalData; if (match[3]) obj = obj[match[2]][match[3]]; if (match[5]) obj = obj[match[5]]; } } return obj; }';
1371
+ $script .= "\n".'if (typeof wfu_run_js == "undefined") function wfu_run_js(obj_str, func) { if (typeof GlobalData == "undefined") { if (typeof window.WFU_JS_BANK == "undefined") WFU_JS_BANK = []; WFU_JS_BANK.push({obj_str: obj_str, func: func}) } else { var obj = wfu_js_decode_obj(obj_str); if (obj) obj[func].call(obj); } }';
1372
+ return wfu_js_to_HTML($script);
1373
+ }
1374
+
1375
+ /**
1376
+ * Convert PHP Array to JS Object.
1377
+ *
1378
+ * This function converts an associative PHP array into a Javascript object.
1379
+ *
1380
+ * @since 4.0.0
1381
+ *
1382
+ * @param array $arr. The associative PHP array to convert.
1383
+ *
1384
+ * @return string The converted Javascript object as a string.
1385
+ */
1386
+ function wfu_PHP_array_to_JS_object($arr) {
1387
+ $ret = "";
1388
+ foreach ( $arr as $prop => $value ) {
1389
+ if ( is_string($value) ) $ret .= ( $ret == "" ? "" : ", " )."$prop: \"$value\"";
1390
+ elseif ( is_numeric($value) ) $ret .= ( $ret == "" ? "" : ", " )."$prop: $value";
1391
+ elseif ( is_bool($value) ) $ret .= ( $ret == "" ? "" : ", " )."$prop: ".( $value ? "true" : "false" );
1392
+ }
1393
+ return ( $ret == "" ? "{ }" : "{ $ret }" );
1394
+ }
1395
+
1396
+ /**
1397
+ * Convert PHP Array to URL GET Params.
1398
+ *
1399
+ * This function converts an associative PHP array into GET parameters to add in
1400
+ * a URL.
1401
+ *
1402
+ * @since 4.9.0
1403
+ *
1404
+ * @param array $arr. The associative PHP array to convert.
1405
+ *
1406
+ * @return string The converted GET parameters.
1407
+ */
1408
+ function wfu_array_to_GET_params($arr) {
1409
+ $str = "";
1410
+ foreach ( $arr as $key => $var )
1411
+ $str .= ( $str == "" ? "" : "&" ).$key."=".$var;
1412
+
1413
+ return $str;
1414
+ }
1415
+
1416
+ //********************* Shortcode Attribute Functions **************************
1417
+
1418
+ /**
1419
+ * Insert a Category in a List of Categories.
1420
+ *
1421
+ * This function inserts a new category in a list of categories.
1422
+ *
1423
+ * @since 4.1.0
1424
+ *
1425
+ * @param array $categories. The list of categories.
1426
+ * @param string $before_category. Insert the new category before this one.
1427
+ * @param string $new_category. The new category to insert.
1428
+ *
1429
+ * @return array The updated list of categories.
1430
+ */
1431
+ function wfu_insert_category($categories, $before_category, $new_category) {
1432
+ if ( $before_category == "" ) $index = count($categories);
1433
+ else {
1434
+ $index = array_search($before_category, array_keys($categories));
1435
+ if ( $index === false ) $index = count($categories);
1436
+ }
1437
+
1438
+ return array_merge(array_slice($categories, 0, $index), $new_category, array_slice($categories, $index));
1439
+ }
1440
+
1441
+ /**
1442
+ * Insert new Attributes in a List of Attributes.
1443
+ *
1444
+ * This function inserts one or more attributes in a list of attributes.
1445
+ *
1446
+ * @since 4.1.0
1447
+ *
1448
+ * @param array $attributes. The list of attributes.
1449
+ * @param string $in_category. Insert the new attribute in this category.
1450
+ * @param string $in_subcategory. Insert the new attribute in this subcategory.
1451
+ * @param string $position. Position of the new attribute. It can be 'first' or
1452
+ * 'last'.
1453
+ * @param array $new_attributes. The new attributes to insert.
1454
+ *
1455
+ * @return array The updated list of attributes.
1456
+ */
1457
+ function wfu_insert_attributes($attributes, $in_category, $in_subcategory, $position, $new_attributes) {
1458
+ $index = -1;
1459
+ if ( $in_category == "" ) {
1460
+ if ( $position == "first" ) $index = 0;
1461
+ elseif ( $position == "last" ) $index = count($attributes);
1462
+ }
1463
+ else {
1464
+ foreach ( $attributes as $pos => $attribute ) {
1465
+ $match = ( $attribute["category"] == $in_category );
1466
+ if ( $in_subcategory != "" ) $match = $match && ( $attribute["subcategory"] == $in_subcategory );
1467
+ if ( $match ) {
1468
+ if ( $position == "first" ) {
1469
+ $index = $pos;
1470
+ break;
1471
+ }
1472
+ elseif ( $position == "last" ) {
1473
+ $index = $pos + 1;
1474
+ }
1475
+ }
1476
+ }
1477
+ }
1478
+ if ( $index > -1 ) array_splice($attributes, $index, 0, $new_attributes);
1479
+
1480
+ return $attributes;
1481
+ }
1482
+
1483
+ //********************* Plugin Options Functions *******************************
1484
+
1485
+ /**
1486
+ * Get Server Environment.
1487
+ *
1488
+ * This function gets the server environment, whether it is 32 or 64 bit.
1489
+ *
1490
+ * @since 2.6.0
1491
+ *
1492
+ * @redeclarable
1493
+ *
1494
+ * @return string The server environment, '32bit' or '64bit'.
1495
+ */
1496
+ function wfu_get_server_environment() {
1497
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
1498
+ $php_env = '';
1499
+ if ( PHP_INT_SIZE == 4 ) $php_env = '32bit';
1500
+ elseif ( PHP_INT_SIZE == 8 ) $php_env = '64bit';
1501
+ else {
1502
+ $int = "9223372036854775807";
1503
+ $int = intval($int);
1504
+ if ($int == 9223372036854775807) $php_env = '64bit';
1505
+ elseif ($int == 2147483647) $php_env = '32bit';
1506
+ }
1507
+
1508
+ return $php_env;
1509
+ }
1510
+
1511
+ /**
1512
+ * Get AJAX URL.
1513
+ *
1514
+ * This function gets the URL of admin-ajax.php for AJAX requests.
1515
+ *
1516
+ * @since 3.7.2
1517
+ *
1518
+ * @redeclarable
1519
+ *
1520
+ * @return string The full URL for AJAX requests.
1521
+ */
1522
+ function wfu_ajaxurl() {
1523
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
1524
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
1525
+ return ( $plugin_options['admindomain'] == 'siteurl' || $plugin_options['admindomain'] == '' ? site_url("wp-admin/admin-ajax.php") : ( $plugin_options['admindomain'] == 'adminurl' ? admin_url("admin-ajax.php") : home_url("wp-admin/admin-ajax.php") ) );
1526
+ }
1527
+
1528
+ /**
1529
+ * Get Plugin Environment Variable Value.
1530
+ *
1531
+ * This function gets the value of a plugin's environment variable.
1532
+ *
1533
+ * @since 3.7.1
1534
+ *
1535
+ * @param string $varname The name of the environment variable.
1536
+ *
1537
+ * @return mixed The value of the environment variable.
1538
+ */
1539
+ function WFU_VAR($varname) {
1540
+ if ( !isset($GLOBALS["WFU_GLOBALS"][$varname]) ) return false;
1541
+ if ( $GLOBALS["WFU_GLOBALS"][$varname][5] ) return $GLOBALS["WFU_GLOBALS"][$varname][3];
1542
+ //in case the environment variable is hidden then return the default value
1543
+ else return $GLOBALS["WFU_GLOBALS"][$varname][2];
1544
+ }
1545
+
1546
+ /**
1547
+ * Get Plugin Version.
1548
+ *
1549
+ * This function gets the plugin's version.
1550
+ *
1551
+ * @since 2.4.6
1552
+ *
1553
+ * @return string The plugin's version.
1554
+ */
1555
+ function wfu_get_plugin_version() {
1556
+ $plugin_data = get_plugin_data(WPFILEUPLOAD_PLUGINFILE);
1557
+ return $plugin_data['Version'];
1558
+ }
1559
+
1560
+ /**
1561
+ * Get Plugin's Latest Version.
1562
+ *
1563
+ * This function gets the plugin's latest version from Iptanus Services Server.
1564
+ *
1565
+ * @since 2.4.6
1566
+ *
1567
+ * @redeclarable
1568
+ *
1569
+ * @return string The plugin's latest version.
1570
+ */
1571
+ function wfu_get_latest_version() {
1572
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
1573
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
1574
+ $postfields = array();
1575
+ $postfields['action'] = 'wfuca_check_latest_version_free';
1576
+ $postfields['version_hash'] = WFU_VERSION_HASH;
1577
+ $url = ( $plugin_options["altserver"] == "1" && trim(WFU_VAR("WFU_ALT_IPTANUS_SERVER")) != "" ? ( trim(WFU_VAR("WFU_ALT_VERSION_SERVER")) != "" ? trim(WFU_VAR("WFU_ALT_VERSION_SERVER")) : trim(WFU_VAR("WFU_ALT_IPTANUS_SERVER")).'/wp-admin/admin-ajax.php' ) : WFU_VERSION_SERVER_URL );
1578
+ $result = null;
1579
+ if ( WFU_VAR("WFU_DISABLE_VERSION_CHECK") != "true" )
1580
+ $result = wfu_post_request($url, $postfields, false, false, 10);
1581
+ return $result;
1582
+ }
1583
+
1584
+ /**
1585
+ * Compare Current and Latest Version.
1586
+ *
1587
+ * This function compares curent version with latest one.
1588
+ *
1589
+ * @since 2.4.6
1590
+ *
1591
+ * @param string $current The curent plugin version.
1592
+ * @param string $latest The latest plugin version.
1593
+ *
1594
+ * @return string The comparison result. It can have the following values:
1595
+ * 'equal': both versions are equal.
1596
+ * 'lower': current version is lower than latest.
1597
+ * 'current version invalid' current version is invalid.
1598
+ * 'latest version invalid' latest version is invalid.
1599
+ */
1600
+ function wfu_compare_versions($current, $latest) {
1601
+ $ret['status'] = true;
1602
+ $ret['custom'] = false;
1603
+ $ret['result'] = 'equal';
1604
+ $res = preg_match('/^([0-9]*)\.([0-9]*)\.([0-9]*)(.*)/', $current, $cur_data);
1605
+ if ( !$res || count($cur_data) < 5 )
1606
+ return array( 'status' => false, 'custom' => false, 'result' => 'current version invalid' );
1607
+ if ( $cur_data[1] == '' || $cur_data[2] == '' || $cur_data[3] == '' )
1608
+ return array( 'status' => false, 'custom' => false, 'result' => 'current version invalid' );
1609
+ $custom = ( $cur_data[4] != '' );
1610
+ $res = preg_match('/^([0-9]*)\.([0-9]*)\.([0-9]*)/', $latest, $lat_data);
1611
+ if ( !$res || count($lat_data) < 4 )
1612
+ return array( 'status' => false, 'custom' => $custom, 'result' => 'latest version invalid' );
1613
+ if ( $lat_data[1] == '' || $lat_data[2] == '' || $lat_data[3] == '' )
1614
+ return array( 'status' => false, 'custom' => $custom, 'result' => 'latest version invalid' );
1615
+ if ( intval($cur_data[1]) < intval($lat_data[1]) )
1616
+ return array( 'status' => true, 'custom' => $custom, 'result' => 'lower' );
1617
+ elseif ( intval($cur_data[1]) > intval($lat_data[1]) )
1618
+ return array( 'status' => false, 'custom' => $custom, 'result' => 'current version invalid' );
1619
+ if ( intval($cur_data[2]) < intval($lat_data[2]) )
1620
+ return array( 'status' => true, 'custom' => $custom, 'result' => 'lower' );
1621
+ elseif ( intval($cur_data[2]) > intval($lat_data[2]) )
1622
+ return array( 'status' => false, 'custom' => $custom, 'result' => 'current version invalid' );
1623
+ if ( intval($cur_data[3]) < intval($lat_data[3]) )
1624
+ return array( 'status' => true, 'custom' => $custom, 'result' => 'lower' );
1625
+ elseif ( intval($cur_data[3]) > intval($lat_data[3]) )
1626
+ return array( 'status' => false, 'custom' => $custom, 'result' => 'current version invalid' );
1627
+ return array( 'status' => true, 'custom' => $custom, 'result' => 'equal' );
1628
+ }
1629
+
1630
+ //********************* File / Directory Functions *****************************
1631
+
1632
+ /**
1633
+ * Get Root Path of Website.
1634
+ *
1635
+ * This function gets the root (absolute) path of the website. If it cannot be
1636
+ * retrieved then content path is returned.
1637
+ *
1638
+ * @since 4.0.0
1639
+ *
1640
+ * @return string The absolute path of the website.
1641
+ */
1642
+ function wfu_abspath() {
1643
+ $path = WP_CONTENT_DIR;
1644
+ //remove trailing slash if exists
1645
+ if ( substr($path, -1) == '/' ) $path = substr($path, 0, -1);
1646
+ $pos = strrpos($path, '/');
1647
+ //to find abspath we go one dir up from content path
1648
+ if ( $pos !== false ) $path = substr($path, 0, $pos + 1);
1649
+ //else if we cannot go up we stay at content path adding a trailing slash
1650
+ else $path .= '/';
1651
+
1652
+ return $path;
1653
+ }
1654
+
1655
+ /**
1656
+ * Extract Extension from Filename.
1657
+ *
1658
+ * This function extracts the extension part from filename.
1659
+ *
1660
+ * @since 3.8.0
1661
+ *
1662
+ * @param string $basename The filename to extract the extension from.
1663
+ * @param bool $with_dot Optional. If true the dot symbol will be included in
1664
+ * the extension.
1665
+ *
1666
+ * @return string The extracted extension.
1667
+ */
1668
+ function wfu_fileext($basename, $with_dot = false) {
1669
+ if ( $with_dot ) return preg_replace("/^.*?(\.[^.]*)?$/", "$1", $basename);
1670
+ else return preg_replace("/^.*?(\.([^.]*))?$/", "$2", $basename);
1671
+ }
1672
+
1673
+ /**
1674
+ * Extract Name Part from Filename.
1675
+ *
1676
+ * This function extracts the name part from filename without the extension.
1677
+ *
1678
+ * @since 3.8.0
1679
+ *
1680
+ * @param string $basename The filename to extract the name part from.
1681
+ *
1682
+ * @return string The extracted name part.
1683
+ */
1684
+ function wfu_filename($basename) {
1685
+ return preg_replace("/^(.*?)(\.[^.]*)?$/", "$1", $basename);
1686
+ }
1687
+
1688
+ /**
1689
+ * Extract Filename From Path.
1690
+ *
1691
+ * This function extracts the filename from path.
1692
+ *
1693
+ * @since 2.6.0
1694
+ *
1695
+ * @param string $path The path to extract the filename from.
1696
+ *
1697
+ * @return string The extracted filename.
1698
+ */
1699
+ function wfu_basename($path) {
1700
+ if ( !$path || $path == "" ) return "";
1701
+ return preg_replace('/.*(\\\\|\\/)/', '', $path);
1702
+ }
1703
+
1704
+ /**
1705
+ * Extract Dir From Path.
1706
+ *
1707
+ * This function extracts the dir part from path without the filename.
1708
+ *
1709
+ * @since 2.7.1
1710
+ *
1711
+ * @param string $path The path to extract the dir part from.
1712
+ *
1713
+ * @return string The extracted dir part.
1714
+ */
1715
+ function wfu_basedir($path) {
1716
+ if ( !$path || $path == "" ) return "";
1717
+ return substr($path, 0, strlen($path) - strlen(wfu_basename($path)));
1718
+ }
1719
+
1720
+ /**
1721
+ * Convert Absolute Path to Relative.
1722
+ *
1723
+ * This function converts an absolute path to relative one by removing the
1724
+ * root path of the website. If the path points to an FTP location then no
1725
+ * conversion happens. If the path is outside the root, then 'abs:' is appended
1726
+ * to the path.
1727
+ *
1728
+ * @since 3.1.0
1729
+ *
1730
+ * @param string $path The absolute path.
1731
+ *
1732
+ * @return string The relative path.
1733
+ */
1734
+ function wfu_path_abs2rel($path) {
1735
+ $abspath_notrailing_slash = substr(wfu_abspath(), 0, -1);
1736
+ if ( substr($path, 0, 6) == 'ftp://' || substr($path, 0, 7) == 'ftps://' || substr($path, 0, 7) == 'sftp://' || substr($path, 0, 7) == 'remote:' ) return $path;
1737
+ else {
1738
+ $is_outside_root = ( substr($path, 0, strlen($abspath_notrailing_slash)) != $abspath_notrailing_slash );
1739
+ if ( $is_outside_root ) return 'abs:'.$path;
1740
+ // else return str_replace($abspath_notrailing_slash, "", $path);
1741
+ else return substr($path, strlen($abspath_notrailing_slash));
1742
+ }
1743
+ }
1744
+
1745
+ /**
1746
+ * Convert Relative Path to Absolute.
1747
+ *
1748
+ * This function converts a relative path to absolute one by prepending the root
1749
+ * path of the website.
1750
+ *
1751
+ * @since 3.1.0
1752
+ *
1753
+ * @param string $path The relative path.
1754
+ *
1755
+ * @return string The absolute path.
1756
+ */
1757
+ function wfu_path_rel2abs($path) {
1758
+ if ( substr($path, 0, 1) == "/" ) $path = substr($path, 1);
1759
+ if ( substr($path, 0, 6) == 'ftp://' || substr($path, 0, 7) == 'ftps://' || substr($path, 0, 7) == 'sftp://' || substr($path, 0, 7) == 'remote:' ) return $path;
1760
+ elseif ( substr($path, 0, 4) == 'abs:' ) return substr($path, 4);
1761
+ else return wfu_abspath().$path;
1762
+ }
1763
+
1764
+ /**
1765
+ * Delete an Uploaded File.
1766
+ *
1767
+ * This function deletes an uploaded file from the website. It marks the file as
1768
+ * deleted in the database. It also deletes any linked attachments or
1769
+ * thumbnails.
1770
+ *
1771
+ * @since 4.2.0
1772
+ *
1773
+ * @redeclarable
1774
+ *
1775
+ * @param string $filepath The path of the file to delete.
1776
+ * @param int $userid The ID of the user who performs the deletion.
1777
+ * @param object $filerec Optional. The db record of the file, if available.
1778
+ *
1779
+ * @return bool True if the deletion succeeded, false otherwise.
1780
+ */
1781
+ function wfu_delete_file_execute($filepath, $userid, $filerec = null) {
1782
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
1783
+ if ( $filerec == null ) $filedata = wfu_get_filedata($filepath);
1784
+ else $filedata = wfu_get_filedata_from_rec($filerec, true, false, false);
1785
+ $delete_rec = true;
1786
+ if ( $delete_rec ) $retid = wfu_log_action('delete', $filepath, $userid, '', 0, 0, '', null, $filerec);
1787
+ $result = wfu_unlink($filepath, "wfu_delete_file_execute");
1788
+ if ( !$result ) wfu_revert_log_action($retid);
1789
+ elseif ( $delete_rec ) {
1790
+ //delete linked attachment if exists and it is allowed to be deleted
1791
+ if ( $filedata != null && isset($filedata["media"]) && WFU_VAR("WFU_UPDATE_MEDIA_ON_DELETE") == "true" )
1792
+ wp_delete_attachment( $filedata["media"]["attach_id"] );
1793
+ }
1794
+
1795
+ return $result;
1796
+ }
1797
+
1798
+ /**
1799
+ * Extract FTP Information From ftpinfo Attribute.
1800
+ *
1801
+ * This function extracts FTP information from ftpinfo attribute of the uploader
1802
+ * shortcode.
1803
+ *
1804
+ * @since 4.11.2
1805
+ *
1806
+ * @param string $ftpdata The ftpinfo attribute.
1807
+ *
1808
+ * @return array {
1809
+ * An array of extracted FTP information.
1810
+ *
1811
+ * @type bool $error Defines whether there was an error during
1812
+ * extraction of FTP information.
1813
+ * @type array $data {
1814
+ * The extracted FTP information.
1815
+ *
1816
+ * @type string $username The FTP login username.
1817
+ * @type string $password The FTP login password.
1818
+ * @type string $ftpdomain The FTP domain.
1819
+ * @type string $port The FTP port.
1820
+ * @type bool $sftp Defines whether sFTP connection will be used.
1821
+ * }
1822
+ * }
1823
+ */
1824
+ function wfu_decode_ftpinfo($ftpdata) {
1825
+ $ret = array(
1826
+ "error" => true,
1827
+ "data" => array(
1828
+ "username" => "",
1829
+ "password" => "",
1830
+ "ftpdomain" => "",
1831
+ "port" => "",
1832
+ "sftp" => false
1833
+ )
1834
+ );
1835
+ $ftpdata_flat = str_replace(array('\\:', '\\@'), array('\\_', '\\_'), $ftpdata);
1836
+ $pos1 = strpos($ftpdata_flat, ":");
1837
+ $pos2 = strpos($ftpdata_flat, "@");
1838
+ if ( $pos1 && $pos2 && $pos2 > $pos1 ) {
1839
+ $ret["error"] = false;
1840
+ $ret["data"]["username"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), substr($ftpdata, 0, $pos1));
1841
+ $ret["data"]["password"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), substr($ftpdata, $pos1 + 1, $pos2 - $pos1 - 1));
1842
+ $ftp_host = substr($ftpdata, $pos2 + 1);
1843
+ $ret["data"]["ftpdomain"] = preg_replace("/:.*/", "", $ftp_host);
1844
+ if ( trim($ret["data"]["ftpdomain"]) == "" ) $ret["error"] = true;
1845
+ $ftp_port = preg_replace("/^[^:]*:?/", "", $ftp_host);
1846
+ if ( substr($ftp_port, 0, 1) == "s" ) {
1847
+ $ret["data"]["sftp"] = true;
1848
+ $ftp_port = substr($ftp_port, 1);
1849
+ }
1850
+ $ret["data"]["port"] = $ftp_port;
1851
+ }
1852
+ elseif ( $pos2 ) {
1853
+ $ret["error"] = false;
1854
+ $ret["data"]["username"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), substr($ftpdata, 0, $pos2));
1855
+ $ftp_host = substr($ftpdata, $pos2 + 1);
1856
+ $ret["data"]["ftpdomain"] = preg_replace("/:.*/", "", $ftp_host);
1857
+ if ( trim($ret["data"]["ftpdomain"]) == "" ) $ret["error"] = true;
1858
+ $ftp_port = preg_replace("/^[^:]*:?/", "", $ftp_host);
1859
+ if ( substr($ftp_port, 0, 1) == "s" ) {
1860
+ $ret["data"]["sftp"] = true;
1861
+ $ftp_port = substr($ftp_port, 1);
1862
+ }
1863
+ $ret["data"]["port"] = $ftp_port;
1864
+ }
1865
+ elseif ( $pos1 ) {
1866
+ $ret["error"] = true;
1867
+ $ret["data"]["username"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), substr($ftpdata, 0, $pos1));
1868
+ $ret["data"]["password"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'),substr($ftpdata, $pos1 + 1));
1869
+ }
1870
+ else {
1871
+ $ret["error"] = true;
1872
+ $ret["data"]["username"] = str_replace(array('\\\\:', '\\\\@'), array(':', '@'), $ftpdata);
1873
+ }
1874
+
1875
+ return $ret;
1876
+ }
1877
+
1878
+ /**
1879
+ * Extract FTP Information From FTP URL.
1880
+ *
1881
+ * This function extracts FTP information from an FTP URL.
1882
+ *
1883
+ * @since 4.15.0
1884
+ *
1885
+ * @param string $url The FTP URL.
1886
+ *
1887
+ * @return array {
1888
+ * An array of extracted FTP information.
1889
+ *
1890
+ * @type bool $error Defines whether there was an error during
1891
+ * extraction of FTP information.
1892
+ * @type array $data {
1893
+ * The extracted FTP information.
1894
+ *
1895
+ * @type string $username The FTP login username.
1896
+ * @type string $password The FTP login password.
1897
+ * @type string $ftpdomain The FTP domain.
1898
+ * @type string $port The FTP port.
1899
+ * @type bool $sftp Defines whether sFTP connection will be used.
1900
+ * @type string $filepath The local path to the file.
1901
+ * }
1902
+ * }
1903
+ */
1904
+ function wfu_decode_ftpurl($url) {
1905
+ $ftpinfo = array(
1906
+ "error" => true,
1907
+ "data" => array(
1908
+ "username" => "",
1909
+ "password" => "",
1910
+ "ftpdomain" => "",
1911
+ "port" => "",
1912
+ "sftp" => false,
1913
+ "filepath" => ""
1914
+ )
1915
+ );
1916
+ if ( substr($url, 0, 6) != "ftp://" && substr($url, 0, 7) != "sftp://" ) return $ftpinfo;
1917
+ $issftp = ( substr($url, 0, 7) == "sftp://" );
1918
+ $filepath = ( $issftp ? substr($url, 7) : substr($url, 6) );
1919
+ $pos = strpos($filepath, '/');
1920
+ if ( $pos === false ) return $ftpinfo;
1921
+ //separate sftp info
1922
+ $ftpdata = substr($filepath, 0, $pos);
1923
+ $filepath = substr($filepath, $pos);
1924
+ $ftpinfo = wfu_decode_ftpinfo($ftpdata);
1925
+ if ( $ftpinfo["error"] ) return $ftpinfo;
1926
+ $data = $ftpinfo["data"];
1927
+ //decode encoded characters in username and password
1928
+ $data["username"] = str_replace(array('%40', '%3A', '%2F'), array('@', ':', '/'), $data["username"]);
1929
+ $data["password"] = str_replace(array('%40', '%3A', '%2F'), array('@', ':', '/'), $data["password"]);
1930
+ $data["sftp"] = $issftp;
1931
+ if ( $data["port"] == "" ) $data["port"] = ( $issftp ? "22" : "80" );
1932
+ $data["filepath"] = $filepath;
1933
+ $ftpinfo["data"] = $data;
1934
+ return $ftpinfo;
1935
+ }
1936
+
1937
+ /**
1938
+ * Hide Credentials From FTP URL.
1939
+ *
1940
+ * This function hides strips username and password information from an FTP URL.
1941
+ *
1942
+ * @since 4.15.0
1943
+ *
1944
+ * @param string $url The file URL.
1945
+ *
1946
+ * @return string The stripped URL.
1947
+ */
1948
+ function wfu_hide_credentials_from_ftpurl($url) {
1949
+ return preg_replace("/^(ftp|sftp)(:\/\/)([^@]*@)(.*$)/", "$1$2$4", $url);
1950
+ }
1951
+
1952
+ /**
1953
+ * Get Full Upload Path.
1954
+ *
1955
+ * This function calculates the full upload path of an uploader shortcode from
1956
+ * its attributes.
1957
+ *
1958
+ * @since 2.1.2
1959
+ *
1960
+ * @param array $params The shortcode attributes.
1961
+ *
1962
+ * @return string The full uplod path.
1963
+ */
1964
+ function wfu_upload_plugin_full_path( $params ) {
1965
+ $path = $params["uploadpath"];
1966
+ if ( $params["accessmethod"] == 'ftp' && $params["ftpinfo"] != '' && $params["useftpdomain"] == "true" ) {
1967
+ //remove parent folder symbol (..) in path so that the path does not go outside host
1968
+ $ftpdata = str_replace('..', '', $params["ftpinfo"]);
1969
+ $ftpinfo = wfu_decode_ftpinfo($ftpdata);
1970
+ if ( !$ftpinfo["error"] ) {
1971
+ $data = $ftpinfo["data"];
1972
+ //extract relative FTP path
1973
+ $ftp_port = $data["port"];
1974
+ if ( $data["sftp"] && $ftp_port == "" ) $ftp_port = "22";
1975
+ $ftp_host = $data["ftpdomain"].( $ftp_port != "" ? ":".$ftp_port : "" );
1976
+ $ftp_username = str_replace(array('@', ':', '/'), array('%40', '%3A', '%2F'), $data["username"]); //if username contains @, :, / characters then encode them
1977
+ $ftp_password = str_replace(array('@', ':', '/'), array('%40', '%3A', '%2F'), $data["password"]); //if username contains @, :, / characters then encode them
1978
+ $start_folder = ( $data["sftp"] ? 's' : '' ).'ftp://'.$ftp_username.':'.$ftp_password."@".$ftp_host.'/';
1979
+ }
1980
+ else $start_folder = 'ftp://'.$params["ftpinfo"].'/';
1981
+ }
1982
+ else $start_folder = WP_CONTENT_DIR.'/';
1983
+ if ($path) {
1984
+ if ( $path == ".." || substr($path, 0, 3) == "../" ) {
1985
+ $start_folder = wfu_abspath();
1986
+ $path = substr($path, 2, strlen($path) - 2);
1987
+ }
1988
+ //remove additional parent folder symbols (..) in path so that the path does not go outside the $start_folder
1989
+ $path = str_replace('..', '', $path);
1990
+ if ( substr($path, 0, 1) == "/" ) $path = substr($path, 1, strlen($path) - 1);
1991
+ if ( substr($path, -1, 1) == "/" ) $path = substr($path, 0, strlen($path) - 1);
1992
+ $full_upload_path = $start_folder;
1993
+ if ( $path != "" ) $full_upload_path .= $path.'/';
1994
+ }
1995
+ else {
1996
+ $full_upload_path = $start_folder;
1997
+ }
1998
+ return $full_upload_path;
1999
+ }
2000
+
2001
+ /**
2002
+ * Get Full Upload Path.
2003
+ *
2004
+ * This function calculates the full upload path of an uploader shortcode from
2005
+ * its attributes.
2006
+ *
2007
+ * @since 2.1.2
2008
+ *
2009
+ * @param array $params The shortcode attributes.
2010
+ *
2011
+ * @return string The full upload path.
2012
+ */
2013
+ function wfu_upload_plugin_directory( $path ) {
2014
+ $dirparts = explode("/", $path);
2015
+ return $dirparts[count($dirparts) - 1];
2016
+ }
2017
+
2018
+ /**
2019
+ * Extract Additional Data From Complex Path.
2020
+ *
2021
+ * This function is used to extract sort, filename, filter or ID information
2022
+ * from a complex path. A complex path is used by the plugin to pass additional
2023
+ * information between requests. In a complex path sort, filename, filter and ID
2024
+ * information are stored as [[-sort]], {{filename}}, ((filter)) and [{id}].
2025
+ *
2026
+ * @since 2.2.1
2027
+ *
2028
+ * @param string $path The complex path.
2029
+ *
2030
+ * @return array {
2031
+ * Additional data extracted from path.
2032
+ *
2033
+ * @type string $path The clean path.
2034
+ * @type string $sort Sort information of a file list.
2035
+ * @type string $file Filename of a specific file.
2036
+ * @type string $filter Filter information of a file list.
2037
+ * @type string $id Record ID of a specific file.
2038
+ * }
2039
+ */
2040
+ function wfu_extract_sortdata_from_path($path) {
2041
+ $ret['path'] = $path;
2042
+ $ret['sort'] = "";
2043
+ $ret['file'] = "";
2044
+ $ret['filter'] = "";
2045
+ $ret['id'] = "";
2046
+ //extract sort info
2047
+ $pos1 = strpos($ret['path'], '[[');
2048
+ $pos2 = strpos($ret['path'], ']]');
2049
+ if ( $pos1 !== false && $pos2 !== false )
2050
+ if ( $pos2 > $pos1 ) {
2051
+ $ret['sort'] = substr($ret['path'], $pos1 + 2, $pos2 - $pos1 - 2);
2052
+ $ret['path'] = str_replace('[['.$ret['sort'].']]', '', $ret['path']);
2053
+ }
2054
+ //extract filename info
2055
+ $pos1 = strpos($ret['path'], '{{');
2056
+ $pos2 = strpos($ret['path'], '}}');
2057
+ if ( $pos1 !== false && $pos2 !== false )
2058
+ if ( $pos2 > $pos1 ) {
2059
+ $ret['file'] = substr($ret['path'], $pos1 + 2, $pos2 - $pos1 - 2);
2060
+ $ret['path'] = str_replace('{{'.$ret['file'].'}}', '', $ret['path']);
2061
+ }
2062
+ //extract filter info
2063
+ $pos1 = strpos($ret['path'], '((');
2064
+ $pos2 = strpos($ret['path'], '))');
2065
+ if ( $pos1 !== false && $pos2 !== false )
2066
+ if ( $pos2 > $pos1 ) {
2067
+ $ret['filter'] = substr($ret['path'], $pos1 + 2, $pos2 - $pos1 - 2);
2068
+ $ret['path'] = str_replace('(('.$ret['filter'].'))', '', $ret['path']);
2069
+ }
2070
+ //extract id info
2071
+ $pos1 = strpos($ret['path'], '[{');
2072
+ $pos2 = strpos($ret['path'], '}]');
2073
+ if ( $pos1 !== false && $pos2 !== false )
2074
+ if ( $pos2 > $pos1 ) {
2075
+ $ret['id'] = substr($ret['path'], $pos1 + 2, $pos2 - $pos1 - 2);
2076
+ $ret['path'] = str_replace('[{'.$ret['id'].'}]', '', $ret['path']);
2077
+ }
2078
+ return $ret;
2079
+ }
2080
+
2081
+ /**
2082
+ * Flatten A Complex Path.
2083
+ *
2084
+ * This function returns only the clean path from a complex path.
2085
+ *
2086
+ * @since 2.2.1
2087
+ *
2088
+ * @param string $path The complex path.
2089
+ *
2090
+ * @return string The clean path.
2091
+ */
2092
+ function wfu_flatten_path($path) {
2093
+ $ret = wfu_extract_sortdata_from_path($path);
2094
+ return $ret['path'];
2095
+ }
2096
+
2097
+ /**
2098
+ * Delete a Directory Recursively.
2099
+ *
2100
+ * This function deletes a directory recursively.
2101
+ *
2102
+ * @since 2.2.1
2103
+ *
2104
+ * @param string $dir The directory to delete.
2105
+ *
2106
+ * @return bool True if the deletion suceeded, false otherwise.
2107
+ */
2108
+ function wfu_delTree($dir) {
2109
+ $files = array_diff(scandir($dir), array('.','..'));
2110
+ foreach ($files as $file) {
2111
+ is_dir("$dir/$file") ? wfu_delTree("$dir/$file") : unlink("$dir/$file");
2112
+ }
2113
+ return rmdir($dir);
2114
+ }
2115
+
2116
+ /**
2117
+ * Get Top-Level Subdirectory Tree of a Directory.
2118
+ *
2119
+ * This function retrieves the first-level subdirectories of a directory.
2120
+ *
2121
+ * @since 2.7.1
2122
+ *
2123
+ * @param string $dir The directory to scan.
2124
+ *
2125
+ * @return array An array of subdirectories.
2126
+ */
2127
+ function wfu_getTree($dir) {
2128
+ $tree = array();
2129
+ $files = @scandir($dir);
2130
+ if ( !is_array($files) ) $files = array();
2131
+ $files = array_diff($files, array('.','..'));
2132
+ foreach ($files as $file) {
2133
+ if ( is_dir("$dir/$file") ) array_push($tree, $file);
2134
+ }
2135
+ return $tree;
2136
+ }
2137
+ /**
2138
+ * Parse List of Folders From subfoldertree Attribute.
2139
+ *
2140
+ * This function calculates the list of subfolders of a subfoldertree attribute
2141
+ * of an uploader shortcode.
2142
+ *
2143
+ * @since 2.4.1
2144
+ *
2145
+ * @redeclarable
2146
+ *
2147
+ * @param string $subfoldertree The subfoldertree attribute of the shortcode.
2148
+ *
2149
+ * @return array {
2150
+ * An array of folders.
2151
+ *
2152
+ * @type array $path An array of folder paths.
2153
+ * @type array $label An array of folder labels.
2154
+ * @type array $level An array of folder levels.
2155
+ * @type array $default An array defining which item is default.
2156
+ * }
2157
+ */
2158
+ function wfu_parse_folderlist($subfoldertree) {
2159
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2160
+ $ret['path'] = array();
2161
+ $ret['label'] = array();
2162
+ $ret['level'] = array();
2163
+ $ret['default'] = array();
2164
+
2165
+ if ( substr($subfoldertree, 0, 4) == "auto" ) return $ret;
2166
+ $subfolders = explode(",", $subfoldertree);
2167
+ if ( count($subfolders) == 0 ) return $ret;
2168
+ if ( count($subfolders) == 1 && trim($subfolders[0]) == "" ) return $ret;
2169
+ $dir_levels = array ( "root" );
2170
+ $prev_level = 0;
2171
+ $level0_count = 0;
2172
+ $default = -1;
2173
+ foreach ($subfolders as $subfolder) {
2174
+ $subfolder = trim($subfolder);
2175
+ $star_count = 0;
2176
+ $start_spaces = "";
2177
+ $is_default = false;
2178
+ //check for folder level
2179
+ while ( $star_count < strlen($subfolder) ) {
2180
+ if ( substr($subfolder, $star_count, 1) == "*" ) {
2181
+ $star_count ++;
2182
+ $start_spaces .= "&nbsp;&nbsp;&nbsp;";
2183
+ }
2184
+ else break;
2185
+ }
2186
+ if ( $star_count - $prev_level <= 1 && ( $star_count > 0 || $level0_count == 0 ) ) {
2187
+ $subfolder = substr($subfolder, $star_count, strlen($subfolder) - $star_count);
2188
+ // check for default value
2189
+ if ( substr($subfolder, 0, 1) == '&' ) {
2190
+ $subfolder = substr($subfolder, 1);
2191
+ $is_default = true;
2192
+ }
2193
+ //split item in folder path and folder name
2194
+ $subfolder_items = explode('/', $subfolder);
2195
+ if ( count($subfolder_items) > 1 && $subfolder_items[1] != "" ) {
2196
+ $subfolder_dir = $subfolder_items[0];
2197
+ $subfolder_label = $subfolder_items[1];
2198
+ }
2199
+ else {
2200
+ $subfolder_dir = $subfolder;
2201
+ $subfolder_label = $subfolder;
2202
+ }
2203
+ if ( $subfolder_dir != "" ) {
2204
+ // set is_default flag to true only for the first default item
2205
+ if ( $is_default && $default == -1 ) $default = count($ret['path']);
2206
+ else $is_default = false;
2207
+ // set flag that root folder has been included (so that it is not included it again)
2208
+ if ( $star_count == 0 ) $level0_count = 1;
2209
+ if ( count($dir_levels) > $star_count ) $dir_levels[$star_count] = $subfolder_dir;
2210
+ else array_push($dir_levels, $subfolder_dir);
2211
+ $subfolder_path = "";
2212
+ for ( $i_count = 1; $i_count <= $star_count; $i_count++) {
2213
+ $subfolder_path .= $dir_levels[$i_count].'/';
2214
+ }
2215
+ array_push($ret['path'], $subfolder_path);
2216
+ array_push($ret['label'], $subfolder_label);
2217
+ array_push($ret['level'], $star_count);
2218
+ array_push($ret['default'], $is_default);
2219
+ $prev_level = $star_count;
2220
+ }
2221
+ }
2222
+ }
2223
+
2224
+ return $ret;
2225
+ }
2226
+
2227
+ /**
2228
+ * Calculate Size of Big File.
2229
+ *
2230
+ * This function calculates the size of a file. It uses a complex approach for
2231
+ * calculating very big files (over 2GB) even in 32bit server environments.
2232
+ *
2233
+ * @since 2.6.0
2234
+ *
2235
+ * @param string $filepath The file path.
2236
+ *
2237
+ * @return The file size.
2238
+ */
2239
+ function wfu_bigfilesize($filepath) {
2240
+ $fp = fopen($filepath, 'r');
2241
+ $pos = 0;
2242
+ if ($fp) {
2243
+ $size = 1073741824;
2244
+ fseek($fp, 0, SEEK_SET);
2245
+ while ($size > 1) {
2246
+ fseek($fp, $size, SEEK_CUR);
2247
+ if (fgetc($fp) === false) {
2248
+ fseek($fp, -$size, SEEK_CUR);
2249
+ $size = (int)($size / 2);
2250
+ }
2251
+ else {
2252
+ fseek($fp, -1, SEEK_CUR);
2253
+ $pos += $size;
2254
+ }
2255
+ }
2256
+ while (fgetc($fp) !== false) $pos++;
2257
+ fclose($fp);
2258
+ }
2259
+
2260
+ return $pos;
2261
+ }
2262
+
2263
+ /**
2264
+ * Alternative Calculate Size of Big File.
2265
+ *
2266
+ * This function calculates the size of a file following an alternative method.
2267
+ * Again, it uses a complex approach for calculating very big files (over 2GB)
2268
+ * even in 32bit server environments.
2269
+ *
2270
+ * @since 2.6.0
2271
+ *
2272
+ * @param string $filepath The file path.
2273
+ *
2274
+ * @return The file size.
2275
+ */
2276
+ function wfu_bigfilesize2($filepath) {
2277
+ $fp = fopen($filepath, 'r');
2278
+ $return = false;
2279
+ if (is_resource($fp)) {
2280
+ if (PHP_INT_SIZE < 8) {
2281
+ // 32bit
2282
+ if (0 === fseek($fp, 0, SEEK_END)) {
2283
+ $return = 0.0;
2284
+ $step = 0x7FFFFFFF;
2285
+ while ($step > 0) {
2286
+ if (0 === fseek($fp, - $step, SEEK_CUR)) {
2287
+ $return += floatval($step);
2288
+ } else {
2289
+ $step >>= 1;
2290
+ }
2291
+ }
2292
+ }
2293
+ } elseif (0 === fseek($fp, 0, SEEK_END)) {
2294
+ // 64bit
2295
+ $return = ftell($fp);
2296
+ }
2297
+ fclose($fp);
2298
+ }
2299
+ return $return;
2300
+ }
2301
+
2302
+ /**
2303
+ * Set Read Position on File.
2304
+ *
2305
+ * This function sets read position on a file. It uses a complex approach for
2306
+ * allowing correct positioning of very big files (over 2GB) even in 32bit
2307
+ * server environments.
2308
+ *
2309
+ * @since 2.6.0
2310
+ *
2311
+ * @param string $fp The file handle of the file.
2312
+ * @param int $pos The read position to set.
2313
+ * @param int $first Optional. If non-zero then position will start from
2314
+ * beginning of file.
2315
+ */
2316
+ function wfu_fseek($fp, $pos, $first = 1) {
2317
+ // set to 0 pos initially, one-time
2318
+ if ( $first ) fseek($fp, 0, SEEK_SET);
2319
+
2320
+ // get pos float value
2321
+ $pos = floatval($pos);
2322
+
2323
+ // within limits, use normal fseek
2324
+ if ( $pos <= PHP_INT_MAX )
2325
+ fseek($fp, $pos, SEEK_CUR);
2326
+ // out of limits, use recursive fseek
2327
+ else {
2328
+ fseek($fp, PHP_INT_MAX, SEEK_CUR);
2329
+ $pos -= PHP_INT_MAX;
2330
+ wfu_fseek($fp, $pos, 0);
2331
+ }
2332
+ }
2333
+
2334
+ /**
2335
+ * Alternative Set Read Position on File.
2336
+ *
2337
+ * This function sets read position on a file following an alternative method.
2338
+ * Again, tt uses a complex approach for allowing correct positioning of very
2339
+ * big files (over 2GB) even in 32bit server environments.
2340
+ *
2341
+ * @since 2.6.0
2342
+ *
2343
+ * @param string $fp The file handle of the file.
2344
+ * @param int $pos The read position to set.
2345
+ *
2346
+ * @return int Upon success, returns 0 otherwise returns -1.
2347
+ */
2348
+ function wfu_fseek2($fp, $pos) {
2349
+ $pos = floatval($pos);
2350
+ if ( $pos <= PHP_INT_MAX ) {
2351
+ return fseek($fp, $pos, SEEK_SET);
2352
+ }
2353
+ else {
2354
+ $fsize = wfu_bigfilesize2($filepath);
2355
+ $opp = $fsize - $pos;
2356
+ if ( 0 === ($ans = fseek($fp, 0, SEEK_END)) ) {
2357
+ $maxstep = 0x7FFFFFFF;
2358
+ $step = $opp;
2359
+ if ( $step > $maxstep ) $step = $maxstep;
2360
+ while ($step > 0) {
2361
+ if ( 0 === ($ans = fseek($fp, - $step, SEEK_CUR)) ) {
2362
+ $opp -= floatval($step);
2363
+ }
2364
+ else {
2365
+ $maxstep >>= 1;
2366
+ }
2367
+ $step = $opp;
2368
+ if ( $step > $maxstep ) $step = $maxstep;
2369
+ }
2370
+ }
2371
+ }
2372
+ return $ans;
2373
+ }
2374
+
2375
+ /**
2376
+ * Write Message to Debug Log.
2377
+ *
2378
+ * This function appends a message to the plugin's debug log file. This file is
2379
+ * located at /wp-content/debug_log.txt.
2380
+ *
2381
+ * @since 2.5.5
2382
+ *
2383
+ * @param string $message The message to log.
2384
+ */
2385
+ function wfu_debug_log($message) {
2386
+ $logpath = WP_CONTENT_DIR.'/debug_log.txt';
2387
+ file_put_contents($logpath, $message, FILE_APPEND);
2388
+ }
2389
+
2390
+ /**
2391
+ * Write Object Contents to Debug Log.
2392
+ *
2393
+ * This function appends the contents of an object to the plugin's debug log
2394
+ * file.
2395
+ *
2396
+ * @since 4.10.0
2397
+ *
2398
+ * @param mixed $obj The object to log.
2399
+ */
2400
+ function wfu_debug_log_obj($obj) {
2401
+ wfu_debug_log(print_r($obj, true));
2402
+ }
2403
+
2404
+ /**
2405
+ * Store Filepath to Safe.
2406
+ *
2407
+ * This function stores a file path into the current user's User Space and
2408
+ * returns a unique code corresponding to the file path. This process is used to
2409
+ * protect file paths from being exposed when needing to pass them as HTTP
2410
+ * request parameters.
2411
+ *
2412
+ * @since 3.0.0
2413
+ *
2414
+ * @param string $path The file path.
2415
+ *
2416
+ * @return The unique code coresponding to the file path.
2417
+ */
2418
+ function wfu_safe_store_filepath($path) {
2419
+ $code = wfu_create_random_string(16);
2420
+ $safe_storage = ( WFU_USVAR_exists('wfu_filepath_safe_storage') ? WFU_USVAR('wfu_filepath_safe_storage') : array() );
2421
+ $safe_storage[$code] = $path;
2422
+ WFU_USVAR_store('wfu_filepath_safe_storage', $safe_storage);
2423
+ return $code;
2424
+ }
2425
+
2426
+ /**
2427
+ * Prepare to Batch Store Filepath to Safe.
2428
+ *
2429
+ * This function assigns a unique code to a file path and stores it to a global
2430
+ * variable so that then it is stored in User Space.
2431
+ *
2432
+ * @since 4.14.3
2433
+ *
2434
+ * @param string $path The file path.
2435
+ *
2436
+ * @return The unique code coresponding to the file path.
2437
+ */
2438
+ function wfu_prepare_to_batch_safe_store_filepath($path) {
2439
+ if ( !isset($GLOBALS["WFU_BATCH_PATHS"]) ) $GLOBALS["WFU_BATCH_PATHS"] = array();
2440
+ $code = wfu_create_random_string(16);
2441
+ $GLOBALS["WFU_BATCH_PATHS"][$code] = $path;
2442
+ return $code;
2443
+ }
2444
+
2445
+ /**
2446
+ * Batch Store Filepaths to Safe.
2447
+ *
2448
+ * This function stores many file paths into the current user's User Space. The
2449
+ * batch function is much quicker that wfu_safe_store_filepath() when a large
2450
+ * number of file paths needs to be stored, because it makes only one call to
2451
+ * the User Space.
2452
+ *
2453
+ * @since 4.14.3
2454
+ */
2455
+ function wfu_batch_safe_store_filepaths() {
2456
+ if ( !isset($GLOBALS["WFU_BATCH_PATHS"]) ) return;
2457
+ $safe_storage = ( WFU_USVAR_exists('wfu_filepath_safe_storage') ? WFU_USVAR('wfu_filepath_safe_storage') : array() );
2458
+ foreach ( $GLOBALS["WFU_BATCH_PATHS"] as $code => $path ) $safe_storage[$code] = $path;
2459
+ WFU_USVAR_store('wfu_filepath_safe_storage', $safe_storage);
2460
+ unset($GLOBALS["WFU_BATCH_PATHS"]);
2461
+ }
2462
+
2463
+ /**
2464
+ * Retrieve Filepath from Safe.
2465
+ *
2466
+ * This function retrieves a file path, previously stored in current user's User
2467
+ * Space, based on its corresponding unique code.
2468
+ *
2469
+ * @since 3.0.0
2470
+ *
2471
+ * @param string $code The unique code.
2472
+ *
2473
+ * @return The file path coresponding to the code.
2474
+ */
2475
+ function wfu_get_filepath_from_safe($code) {
2476
+ //sanitize $code
2477
+ $code = wfu_sanitize_code($code);
2478
+ if ( $code == "" ) return false;
2479
+ //return filepath from session variable, if exists
2480
+ if ( !WFU_USVAR_exists('wfu_filepath_safe_storage') ) return false;
2481
+ $safe_storage = WFU_USVAR('wfu_filepath_safe_storage');
2482
+ if ( !isset($safe_storage[$code]) ) return false;
2483
+ return $safe_storage[$code];
2484
+ }
2485
+
2486
+ /**
2487
+ * Check if File Extension is Restricted.
2488
+ *
2489
+ * This function checks if the extension of a file name is restricted. It also
2490
+ * checks for double extensions. This function is not used anymore.
2491
+ *
2492
+ * @since 3.0.0
2493
+ * @deprecated 3.9.0 Use wfu_file_extension_blacklisted()
2494
+ * @see wfu_file_extension_blacklisted()
2495
+ *
2496
+ * @param string $filename The file name to check.
2497
+ *
2498
+ * @return bool True if extension is restricted, false otherwise.
2499
+ */
2500
+ function wfu_file_extension_restricted($filename) {
2501
+ return (
2502
+ substr($filename, -4) == ".php" ||
2503
+ substr($filename, -3) == ".js" ||
2504
+ substr($filename, -4) == ".pht" ||
2505
+ substr($filename, -5) == ".php3" ||
2506
+ substr($filename, -5) == ".php4" ||
2507
+ substr($filename, -5) == ".php5" ||
2508
+ substr($filename, -6) == ".phtml" ||
2509
+ substr($filename, -4) == ".htm" ||
2510
+ substr($filename, -5) == ".html" ||
2511
+ substr($filename, -9) == ".htaccess" ||
2512
+ strpos($filename, ".php.") !== false ||
2513
+ strpos($filename, ".js.") !== false ||
2514
+ strpos($filename, ".pht.") !== false ||
2515
+ strpos($filename, ".php3.") !== false ||
2516
+ strpos($filename, ".php4.") !== false ||
2517
+ strpos($filename, ".php5.") !== false ||
2518
+ strpos($filename, ".phtml.") !== false ||
2519
+ strpos($filename, ".htm.") !== false ||
2520
+ strpos($filename, ".html.") !== false ||
2521
+ strpos($filename, ".htaccess.") !== false
2522
+ );
2523
+ }
2524
+
2525
+ /**
2526
+ * Convert Time to Human-Readable Format.
2527
+ *
2528
+ * This function converts a time, given in integer format, into a human-readable
2529
+ * one providing number of days, hours, minutes and seconds.
2530
+ *
2531
+ * @since 4.0.0
2532
+ *
2533
+ * @param int $time The time to convert.
2534
+ *
2535
+ * @return string The time in human-readable format.
2536
+ */
2537
+ function wfu_human_time($time) {
2538
+ $time = (int)$time;
2539
+ $days = (int)($time/86400);
2540
+ $time -= $days * 86400;
2541
+ $hours = (int)($time/3600);
2542
+ $time -= $hours * 3600;
2543
+ $minutes = (int)($time/60);
2544
+ $secs = $time - $minutes * 60;
2545
+ $human_time = ( $days > 0 ? $days."d" : "" ).( $hours > 0 ? $hours."h" : "" ).( $minutes > 0 ? $minutes."m" : "" ).( $secs > 0 ? $secs."s" : "" );
2546
+ if ( $human_time == "" ) $human_time == "0s";
2547
+ return $human_time;
2548
+ }
2549
+
2550
+ /**
2551
+ * Convert File Size to Human-Readable Format.
2552
+ *
2553
+ * This function converts a file size, given in bytes, into a human-readable
2554
+ * format providing number of GBs, MBs, KBs and bytes.
2555
+ *
2556
+ * @since 3.1.0
2557
+ *
2558
+ * @param int $size The file size in bytes.
2559
+ * @param string $unit Optional. The size unit to use. It can be GB, MB, KB. If
2560
+ * it is omitted then it will be calculated automatically.
2561
+ *
2562
+ * @return string The file size in human-readable format.
2563
+ */
2564
+ function wfu_human_filesize($size, $unit = "") {
2565
+ if ( ( !$unit && $size >= 1<<30 ) || $unit == "GB" )
2566
+ return number_format($size / (1<<30), 2)."GB";
2567
+ if( ( !$unit && $size >= 1<<20 ) || $unit == "MB" )
2568
+ return number_format($size / (1<<20), 2)."MB";
2569
+ if( ( !$unit && $size >= 1<<10 ) || $unit == "KB" )
2570
+ return number_format($size / (1<<10), 2)."KB";
2571
+ return number_format($size)." bytes";
2572
+ }
2573
+
2574
+ /**
2575
+ * Check if File Exists Including Chunks.
2576
+ *
2577
+ * This function checks if a file exists. It will also return true if chunks of
2578
+ * a file still uploading exist.
2579
+ *
2580
+ * @since 4.12.0
2581
+ *
2582
+ * @param string $path The file path to check.
2583
+ *
2584
+ * @return bool True if file exists, false otherwise.
2585
+ */
2586
+ function wfu_file_exists_extended($path) {
2587
+ if ( wfu_file_exists($path) ) return true;
2588
+
2589
+ return false;
2590
+ }
2591
+
2592
+ /**
2593
+ * Check if File Exists.
2594
+ *
2595
+ * This function checks if a file exists. It is an extension to the original
2596
+ * PHP file_exists() function to take special actions in cases where the file
2597
+ * is stored in an sFTP location or perhaps in other external locations (cloud
2598
+ * services, WebDAV etc.).
2599
+ *
2600
+ * @since 3.9.3
2601
+ *
2602
+ * @redeclarable
2603
+ *
2604
+ * @param string $path The file path to check.
2605
+ * @param string $caller The name of the function that called this one.
2606
+ *
2607
+ * @return bool True if file exists, false otherwise.
2608
+ */
2609
+ function wfu_file_exists($path, $caller = null) {
2610
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2611
+ //For FTP and SFTP paths this function will be executed only under certain
2612
+ //conditions, because it may take a long time.
2613
+ //For FTP paths, execution is determined by 2 variables:
2614
+ // - WFU_FILEOPERATION_IGNOREFTP: This is a general flag to ignore
2615
+ // calculation for all file function.
2616
+ // - WFU_FTPFILEEXISTS_DEFVALUE: This is the value returned in case the
2617
+ // previous flag is true.
2618
+ //If WFU_FTPFILEEXISTS_DEFVALUE starts with an asterisk (*) then it
2619
+ //preceeds over the general flag.
2620
+ //For SFTP paths there are similar variables.
2621
+ if ( substr($path, 0, 6) == "ftp://" ) {
2622
+ $ret = false;
2623
+ $def = WFU_VAR("WFU_FTPFILEEXISTS_DEFVALUE");
2624
+ if ( substr($def, 0, 1) == "*" ) {
2625
+ switch ( $def ) {
2626
+ case "*true": $ret = true; break;
2627
+ case "*false": $ret = false; break;
2628
+ case "*calc": $ret = file_exists($path); break;
2629
+ }
2630
+ }
2631
+ else $ret = ( WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") == "true" ? ( $def == "true" ) : file_exists($path) );
2632
+ return $ret;
2633
+ }
2634
+ elseif ( substr($path, 0, 7) == "sftp://" ) {
2635
+ $ret = false;
2636
+ $def = WFU_VAR("WFU_SFTPFILEEXISTS_DEFVALUE");
2637
+ if ( substr($def, 0, 1) == "*" ) {
2638
+ switch ( $def ) {
2639
+ case "*true": $ret = true; break;
2640
+ case "*false": $ret = false; break;
2641
+ case "*calc": $ret = wfu_file_exists_sftp($path); break;
2642
+ }
2643
+ }
2644
+ else $ret = ( WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") == "true" ? ( $def == "true" ) : wfu_file_exists_sftp($path) );
2645
+ return $ret;
2646
+ }
2647
+ elseif ( substr($path, 0, 7) == "remote:" ) {
2648
+ $ret = false;
2649
+ $def = WFU_VAR("WFU_REMOTEFILEEXISTS_DEFVALUE");
2650
+ if ( substr($def, 0, 1) == "*" ) {
2651
+ switch ( $def ) {
2652
+ case "*true": $ret = true; break;
2653
+ case "*false": $ret = false; break;
2654
+ }
2655
+ }
2656
+ else $ret = ( WFU_VAR("WFU_FILEOPERATION_IGNOREREMOTE") == "true" ? ( $def == "true" ) : true );
2657
+ return $ret;
2658
+ }
2659
+ elseif ( file_exists($path) ) return true;
2660
+
2661
+ return false;
2662
+ }
2663
+
2664
+ /**
2665
+ * Get Info About File.
2666
+ *
2667
+ * This function gets file info. It is an extension to the original PHP stat()
2668
+ * function to take special actions in cases where the file is stored in an sFTP
2669
+ * location or perhaps in other external locations (cloud services, WebDAV
2670
+ * etc.).
2671
+ *
2672
+ * @since 4.15.0
2673
+ *
2674
+ * @redeclarable
2675
+ *
2676
+ * @param string $path The file path to check.
2677
+ * @param string $caller The name of the function that called this one.
2678
+ *
2679
+ * @return array|false Information about the file, or false on error.
2680
+ */
2681
+ function wfu_stat($path, $caller = null) {
2682
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2683
+ if ( substr($path, 0, 6) == "ftp://" ) {
2684
+ $ret = array( "mtime" => 0, "size" => 0 );
2685
+ $def = WFU_VAR("WFU_FTPSTAT_DEFVALUE");
2686
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2687
+ $ret = stat($path);
2688
+ return $ret;
2689
+ }
2690
+ elseif ( substr($path, 0, 7) == "sftp://" ) {
2691
+ $ret = array( "mtime" => 0, "size" => 0 );
2692
+ $def = WFU_VAR("WFU_SFTPSTAT_DEFVALUE");
2693
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2694
+ $ret = wfu_stat_sftp($path);
2695
+ return $ret;
2696
+ }
2697
+ elseif ( substr($path, 0, 7) == "remote:" ) {
2698
+ $ret = array( "mtime" => 0, "size" => 0 );
2699
+ $def = WFU_VAR("WFU_REMOTESTAT_DEFVALUE");
2700
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREREMOTE") != "true" ) )
2701
+ $ret = array( "mtime" => 0, "size" => 0 );
2702
+ return $ret;
2703
+ }
2704
+ else return stat($path);
2705
+ }
2706
+
2707
+ /**
2708
+ * Get Size of File.
2709
+ *
2710
+ * This function gets file size. It is an extension to the original PHP
2711
+ * filesize() function to take special actions in cases where the file is stored
2712
+ * in an sFTP location or perhaps in other external locations (cloud services,
2713
+ * WebDAV etc.).
2714
+ *
2715
+ * @since 4.15.0
2716
+ *
2717
+ * @redeclarable
2718
+ *
2719
+ * @param string $path The file path to check.
2720
+ * @param string $caller The name of the function that called this one.
2721
+ *
2722
+ * @return int|false The file size or false on error.
2723
+ */
2724
+ function wfu_filesize($path, $caller = null) {
2725
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2726
+ if ( substr($path, 0, 6) == "ftp://" ) {
2727
+ $ret = false;
2728
+ $def = WFU_VAR("WFU_FTPFILESIZE_DEFVALUE");
2729
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2730
+ $ret = filesize($path);
2731
+ return $ret;
2732
+ }
2733
+ elseif ( substr($path, 0, 7) == "sftp://" ) {
2734
+ $ret = false;
2735
+ $def = WFU_VAR("WFU_SFTPFILESIZE_DEFVALUE");
2736
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2737
+ $ret = wfu_filesize_sftp($path);
2738
+ return $ret;
2739
+ }
2740
+ elseif ( substr($path, 0, 7) == "remote:" ) {
2741
+ $ret = false;
2742
+ $def = WFU_VAR("WFU_REMOTEFILESIZE_DEFVALUE");
2743
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREREMOTE") != "true" ) )
2744
+ $ret = false;
2745
+ return $ret;
2746
+ }
2747
+ else return filesize($path);
2748
+ }
2749
+
2750
+ /**
2751
+ * Get File Stream Handle.
2752
+ *
2753
+ * This function gets a file stream handle. It is an extension to the original
2754
+ * PHP fopen() function to take special actions in cases where the file is
2755
+ * stored in an sFTP location or perhaps in other external locations (cloud
2756
+ * services, WebDAV etc.).
2757
+ *
2758
+ * @since 4.15.0
2759
+ *
2760
+ * @redeclarable
2761
+ *
2762
+ * @param string $path The file path to check.
2763
+ * @param string $mode The file access mode.
2764
+ * @param string $caller The name of the function that called this one.
2765
+ *
2766
+ * @return resource|false The file stream handle or false on error.
2767
+ */
2768
+ function wfu_fopen($path, $mode, $caller = null) {
2769
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2770
+ if ( substr($path, 0, 6) == "ftp://" ) {
2771
+ $ret = false;
2772
+ $def = WFU_VAR("WFU_FTPFOPEN_DEFVALUE");
2773
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2774
+ $ret = fopen($path, $mode);
2775
+ return $ret;
2776
+ }
2777
+ elseif ( substr($path, 0, 7) == "sftp://" ) {
2778
+ $ret = false;
2779
+ $def = WFU_VAR("WFU_SFTPFOPEN_DEFVALUE");
2780
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2781
+ $ret = wfu_fopen_sftp($path, $mode);
2782
+ return $ret;
2783
+ }
2784
+ elseif ( substr($path, 0, 7) == "remote:" ) {
2785
+ $ret = false;
2786
+ $def = WFU_VAR("WFU_REMOTEFOPEN_DEFVALUE");
2787
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREREMOTE") != "true" ) )
2788
+ $ret = false;
2789
+ return $ret;
2790
+ }
2791
+ else return fopen($path, $mode);
2792
+ }
2793
+
2794
+ /**
2795
+ * Get File Contents.
2796
+ *
2797
+ * This function gets the contents of a file. It is an extension to the original
2798
+ * PHP file_get_contents() function to take special actions in cases where the
2799
+ * file is stored in an sFTP location or perhaps in other external locations
2800
+ * (cloud services, WebDAV etc.).
2801
+ *
2802
+ * @since 4.15.0
2803
+ *
2804
+ * @redeclarable
2805
+ *
2806
+ * @param string $path The file path.
2807
+ * @param string $caller The name of the function that called this one.
2808
+ *
2809
+ * @return string|false The file contents as a string or false on error.
2810
+ */
2811
+ function wfu_file_get_contents($path, $caller = null) {
2812
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2813
+ if ( substr($path, 0, 6) == "ftp://" ) {
2814
+ $ret = false;
2815
+ $def = WFU_VAR("WFU_FTPFILEGETCONTENTS_DEFVALUE");
2816
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2817
+ $ret = file_get_contents($path);
2818
+ return $ret;
2819
+ }
2820
+ elseif ( substr($path, 0, 7) == "sftp://" ) {
2821
+ $ret = false;
2822
+ $def = WFU_VAR("WFU_SFTPFILEGETCONTENTS_DEFVALUE");
2823
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2824
+ $ret = wfu_file_get_contents_sftp($path);
2825
+ return $ret;
2826
+ }
2827
+ elseif ( substr($path, 0, 7) == "remote:" ) {
2828
+ $ret = false;
2829
+ $def = WFU_VAR("WFU_REMOTEFILEGETCONTENTS_DEFVALUE");
2830
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREREMOTE") != "true" ) )
2831
+ $ret = false;
2832
+ return $ret;
2833
+ }
2834
+ else return file_get_contents($path);
2835
+ }
2836
+
2837
+ /**
2838
+ * Get MD5 of File.
2839
+ *
2840
+ * This function gets the md5 signature of a file. It is an extension to the
2841
+ * original PHP md5_file() function to take special actions in cases where the
2842
+ * file is stored in an sFTP location or perhaps in other external locations
2843
+ * (cloud services, WebDAV etc.).
2844
+ *
2845
+ * @since 4.15.0
2846
+ *
2847
+ * @redeclarable
2848
+ *
2849
+ * @param string $path The file path.
2850
+ * @param string $caller The name of the function that called this one.
2851
+ *
2852
+ * @return string|false The md5 of the file or false on error.
2853
+ */
2854
+ function wfu_md5_file($path, $caller = null) {
2855
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2856
+ if ( substr($path, 0, 6) == "ftp://" ) {
2857
+ $ret = false;
2858
+ $def = WFU_VAR("WFU_FTPMD5FILE_DEFVALUE");
2859
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2860
+ $ret = md5_file($path);
2861
+ return $ret;
2862
+ }
2863
+ elseif ( substr($path, 0, 7) == "sftp://" ) {
2864
+ $ret = false;
2865
+ $def = WFU_VAR("WFU_SFTPMD5FILE_DEFVALUE");
2866
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2867
+ $ret = wfu_md5_file_sftp($path);
2868
+ return $ret;
2869
+ }
2870
+ elseif ( substr($path, 0, 7) == "remote:" ) {
2871
+ $ret = false;
2872
+ $def = WFU_VAR("WFU_REMOTEMD5FILE_DEFVALUE");
2873
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREREMOTE") != "true" ) )
2874
+ $ret = false;
2875
+ return $ret;
2876
+ }
2877
+ else return md5_file($path);
2878
+ }
2879
+
2880
+ /**
2881
+ * Delete a File.
2882
+ *
2883
+ * This function deletes a file. It is an extension to the original PHP unlink()
2884
+ * function to take special actions in cases where the file is stored in an sFTP
2885
+ * location or perhaps in other external locations (cloud services, WebDAV
2886
+ * etc.).
2887
+ *
2888
+ * @since 4.15.0
2889
+ *
2890
+ * @redeclarable
2891
+ *
2892
+ * @param string $path The file path.
2893
+ * @param string $caller The name of the function that called this one.
2894
+ *
2895
+ * @return boolean True on success, false on error.
2896
+ */
2897
+ function wfu_unlink($path, $caller = null) {
2898
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
2899
+ if ( substr($path, 0, 6) == "ftp://" ) {
2900
+ $ret = false;
2901
+ $def = WFU_VAR("WFU_FTPUNLINK_DEFVALUE");
2902
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREFTP") != "true" ) )
2903
+ $ret = unlink($path);
2904
+ return $ret;
2905
+ }
2906
+ elseif ( substr($path, 0, 7) == "sftp://" ) {
2907
+ $ret = false;
2908
+ $def = WFU_VAR("WFU_SFTPUNLINK_DEFVALUE");
2909
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNORESFTP") != "true" ) )
2910
+ $ret = wfu_unlink_sftp($path);
2911
+ return $ret;
2912
+ }
2913
+ elseif ( substr($path, 0, 7) == "remote:" ) {
2914
+ $ret = false;
2915
+ $def = WFU_VAR("WFU_REMOTEUNLINK_DEFVALUE");
2916
+ if ( $def == "*calc" || ( substr($def, 0, 1) != "*" && WFU_VAR("WFU_FILEOPERATION_IGNOREREMOTE") != "true" ) )
2917
+ $ret = false;
2918
+ return $ret;
2919
+ }
2920
+ else return unlink($path);
2921
+ }
2922
+
2923
+ /**
2924
+ * Get MIME Type of File.
2925
+ *
2926
+ * This function gets MIME type of a file, using mime_content_type() function if
2927
+ * exists, otherwise it uses finfo_open(). If none of them exist it returns a
2928
+ * MIME type based on file extension.
2929
+ *
2930
+ * @since 4.14.3
2931
+ *
2932
+ * @param int $path The path to the file.
2933
+ *
2934
+ * @return string The MIME type.
2935
+ */
2936
+ function wfu_mime_content_type($path) {
2937
+ if ( function_exists('mime_content_type') ) {
2938
+ $mimetype = mime_content_type($path);
2939
+ return $mimetype;
2940
+ }
2941
+ elseif ( function_exists('finfo_open') ) {
2942
+ $finfo = finfo_open(FILEINFO_MIME_TYPE);
2943
+ $mimetype = finfo_file($finfo, $path);
2944
+ finfo_close($finfo);
2945
+ return $mimetype;
2946
+ }
2947
+ else {
2948
+ $mime_types = array(
2949
+ 'txt' => 'text/plain',
2950
+ 'htm' => 'text/html',
2951
+ 'html' => 'text/html',
2952
+ 'php' => 'text/html',
2953
+ 'css' => 'text/css',
2954
+ 'js' => 'application/javascript',
2955
+ 'json' => 'application/json',
2956
+ 'xml' => 'application/xml',
2957
+ 'swf' => 'application/x-shockwave-flash',
2958
+ 'flv' => 'video/x-flv',
2959
+ // images
2960
+ 'png' => 'image/png',
2961
+ 'jpe' => 'image/jpeg',
2962
+ 'jpeg' => 'image/jpeg',
2963
+ 'jpg' => 'image/jpeg',
2964
+ 'gif' => 'image/gif',
2965
+ 'bmp' => 'image/bmp',
2966
+ 'ico' => 'image/vnd.microsoft.icon',
2967
+ 'tiff' => 'image/tiff',
2968
+ 'tif' => 'image/tiff',
2969
+ 'svg' => 'image/svg+xml',
2970
+ 'svgz' => 'image/svg+xml',
2971
+ // archives
2972
+ 'zip' => 'application/zip',
2973
+ 'rar' => 'application/x-rar-compressed',
2974
+ 'exe' => 'application/x-msdownload',
2975
+ 'msi' => 'application/x-msdownload',
2976
+ 'cab' => 'application/vnd.ms-cab-compressed',
2977
+ // audio/video
2978
+ 'mp3' => 'audio/mpeg',
2979
+ 'qt' => 'video/quicktime',
2980
+ 'mov' => 'video/quicktime',
2981
+ // adobe
2982
+ 'pdf' => 'application/pdf',
2983
+ 'psd' => 'image/vnd.adobe.photoshop',
2984
+ 'ai' => 'application/postscript',
2985
+ 'eps' => 'application/postscript',
2986
+ 'ps' => 'application/postscript',
2987
+ // ms office
2988
+ 'doc' => 'application/msword',
2989
+ 'rtf' => 'application/rtf',
2990
+ 'xls' => 'application/vnd.ms-excel',
2991
+ 'ppt' => 'application/vnd.ms-powerpoint',
2992
+ 'docx' => 'application/msword',
2993
+ 'xlsx' => 'application/vnd.ms-excel',
2994
+ 'pptx' => 'application/vnd.ms-powerpoint',
2995
+ // open office
2996
+ 'odt' => 'application/vnd.oasis.opendocument.text',
2997
+ 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
2998
+ );
2999
+ $filename = wfu_basename($path);
3000
+ $ext = wfu_fileext($filename);
3001
+ if ( array_key_exists($ext, $mime_types) )
3002
+ return $mime_types[$ext];
3003
+ else return 'application/octet-stream';
3004
+ }
3005
+ }
3006
+
3007
+ /**
3008
+ * Custom Attempt to determine the real file type of a file.
3009
+ *
3010
+ * This is a wrapper function of Wordpress wp_check_filetype_and_ext(), which
3011
+ * also takes into account sftp:// filepaths.
3012
+ *
3013
+ * @since 4.15.0
3014
+ *
3015
+ * @param string $file Full path to the file.
3016
+ * @param string $filename The name of the file.
3017
+ *
3018
+ * @return array {
3019
+ * Values for the extension, mime type, and corrected filename.
3020
+ *
3021
+ * @type string|false $ext File extension, or false if the file doesn't
3022
+ * match a mime type.
3023
+ * @type string|false $type File mime type, or false if the file doesn't
3024
+ * match a mime type.
3025
+ * @type string|false $proper_filename File name with its correct extension,
3026
+ * or false if it cannot be determined.
3027
+ * }
3028
+ */
3029
+ function wfu_wp_check_filetype_and_ext( $file, $filename ) {
3030
+ //ignore check for sftp files
3031
+ if ( substr($file, 0, 7) == "sftp://" ) {
3032
+ return array( "proper_filename" => false );
3033
+ }
3034
+ else return wp_check_filetype_and_ext( $file, $filename );
3035
+ }
3036
+
3037
+ //********************* User Functions *****************************************
3038
+
3039
+ /**
3040
+ * Get Matching User Role.
3041
+ *
3042
+ * This function checks if any of the user's roles are included in a list of
3043
+ * roles. If the user is administrator it will match. If 'all' is included in
3044
+ * the list of roles then it will also match. The function returns the matched
3045
+ * role.
3046
+ *
3047
+ * @since 2.1.2
3048
+ *
3049
+ * @param object $user The user to check.
3050
+ * @param array $param_roles A list of roles to match the user.
3051
+ *
3052
+ * @return string The matching role, or 'nomatch'.
3053
+ */
3054
+ function wfu_get_user_role($user, $param_roles) {
3055
+ $result_role = 'nomatch';
3056
+ if ( !empty( $user->roles ) && is_array( $user->roles ) ) {
3057
+ /* Go through the array of the roles of the current user */
3058
+ foreach ( $user->roles as $user_role ) {
3059
+ $user_role = strtolower($user_role);
3060
+ /* if this role matches to the roles in $param_roles or it is
3061
+ administrator or $param_roles allow all roles then it is
3062
+ approved */
3063
+ if ( in_array($user_role, $param_roles) || $user_role == 'administrator' || in_array('all', $param_roles) ) {
3064
+ /* We approve this role of the user and exit */
3065
+ $result_role = $user_role;
3066
+ break;
3067
+ }
3068
+ }
3069
+ }
3070
+ /* if the user has no roles (guest) and guests are allowed, then it is
3071
+ approved */
3072
+ elseif ( in_array('guests', $param_roles) ) {
3073
+ $result_role = 'guest';
3074
+ }
3075
+ return $result_role;
3076
+ }
3077
+
3078
+ /**
3079
+ * Get Valid User Roles.
3080
+ *
3081
+ * This function gets all user's valid roles by checking which of them are
3082
+ * included in $wp_roles global variable.
3083
+ *
3084
+ * @since 3.0.0
3085
+ *
3086
+ * @global array $wp_roles An array of Wordpress roles.
3087
+ *
3088
+ * @param object $user The user to check.
3089
+ *
3090
+ * @return array The list of user's valid roles.
3091
+ */
3092
+ function wfu_get_user_valid_role_names($user) {
3093
+ global $wp_roles;
3094
+
3095
+ $result_roles = array();
3096
+ if ( !empty( $user->roles ) && is_array( $user->roles ) ) {
3097
+ /* get all valid roles */
3098
+ $roles = $wp_roles->get_names();
3099
+ /* Go through the array of the roles of the current user */
3100
+ foreach ( $user->roles as $user_role ) {
3101
+ $user_role = strtolower($user_role);
3102
+ /* If one role of the current user matches to the roles allowed to upload */
3103
+ if ( in_array($user_role, array_keys($roles)) ) array_push($result_roles, $user_role);
3104
+ }
3105
+ }
3106
+
3107
+ return $result_roles;
3108
+ }
3109
+
3110
+ //*********************** DB Functions *****************************************************************************************************
3111
+
3112
+ /**
3113
+ * Log Action to Database.
3114
+ *
3115
+ * This function logs plugin's actions (uploads, renames, deletions etc.) in the
3116
+ * plugin's database tables. This function stores upload information about all
3117
+ * uploaded files.
3118
+ *
3119
+ * @since 2.4.1
3120
+ *
3121
+ * @global object $wpdb The Wordpress database object.
3122
+ *
3123
+ * @param string $action The action to log.
3124
+ * @param string $filepath The file path of the involved file.
3125
+ * @param int $userid The ID of the user who performs the action.
3126
+ * @param string $uploadid The unique ID of the upload, if this is an upload
3127
+ * action.
3128
+ * @param int $pageid The ID of the upload page, if this is an upload action.
3129
+ * @param int $blogid The ID of the blog (in case this is a multisite
3130
+ * installation).
3131
+ * @param int $sid The plugin ID of the upload form, if this is an upload
3132
+ * action.
3133
+ * @param array $userdata {
3134
+ * Any additional user data to store with the uploaded files.
3135
+ *
3136
+ * @type array $userdata_field {
3137
+ * Individual user data field.
3138
+ *
3139
+ * @type string $label The title of the userdata field.
3140
+ * @type string $value The value entered by the user in the field.
3141
+ * }
3142
+ * }
3143
+ * @param object $filerec Optional. The db record of the file, if available.
3144
+ * @param bool $check_file_existence Optional. Whether wfu_file_exists will run.
3145
+ *
3146
+ * @return int The ID of the new record that was added in the database, or 0 if
3147
+ * no record was added.
3148
+ */
3149
+ function wfu_log_action($action, $filepath, $userid, $uploadid, $pageid, $blogid, $sid, $userdata, $filerec = null, $check_file_existence = true) {
3150
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3151
+ global $wpdb;
3152
+ $table_name1 = $wpdb->prefix . "wfu_log";
3153
+ $table_name2 = $wpdb->prefix . "wfu_userdata";
3154
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
3155
+
3156
+ if ( $action == 'datasubmit' || substr($action, 0, 5) == 'other' ) $check_file_existence = false;
3157
+ if ( $check_file_existence && !wfu_file_exists($filepath, "wfu_log_action") ) return;
3158
+
3159
+ //$parts = pathinfo($filepath);
3160
+ $relativepath = wfu_path_abs2rel($filepath);
3161
+ // if ( substr($relativepath, 0, 1) != '/' ) $relativepath = '/'.$relativepath;
3162
+
3163
+ $retid = 0;
3164
+ if ( $action == 'upload' || $action == 'include' || $action == 'datasubmit' ) {
3165
+ if ( $action == 'upload' || $action == 'include' ) {
3166
+ // calculate and store file hash if this setting is enabled from Settings
3167
+ $filehash = '';
3168
+ if ( $plugin_options['hashfiles'] == '1' ) $filehash = wfu_md5_file($filepath, "wfu_log_action");
3169
+ // calculate file size
3170
+ $filesize = wfu_filesize($filepath, "wfu_log_action");
3171
+ // first make obsolete records having the same file path because the old file has been replaced
3172
+ $oldrecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE filepath = \''.esc_sql($relativepath).'\' AND date_to = 0');
3173
+ if ( $oldrecs ) {
3174
+ foreach ( $oldrecs as $oldrec ) wfu_make_rec_obsolete($oldrec);
3175
+ }
3176
+ }
3177
+ // attempt to create new log record
3178
+ $now_date = date('Y-m-d H:i:s');
3179
+ if ( $wpdb->insert($table_name1,
3180
+ array(
3181
+ 'userid' => $userid,
3182
+ 'uploaduserid' => $userid,
3183
+ 'uploadtime' => time(),
3184
+ 'sessionid' => wfu_get_session_id(),
3185
+ 'filepath' => ( $action == 'datasubmit' ? '' : $relativepath ),
3186
+ 'filehash' => ( $action == 'datasubmit' ? '' : $filehash ),
3187
+ 'filesize' => ( $action == 'datasubmit' ? 0 : $filesize ),
3188
+ 'uploadid' => $uploadid,
3189
+ 'pageid' => $pageid,
3190
+ 'blogid' => $blogid,
3191
+ 'sid' => $sid,
3192
+ 'date_from' => $now_date,
3193
+ 'date_to' => 0,
3194
+ 'action' => $action
3195
+ ),
3196
+ array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s' )) !== false ) {
3197
+ $retid = $wpdb->insert_id;
3198
+ // if new log record has been created, also create user data records
3199
+ if ( $userdata != null && $uploadid != '' ) {
3200
+ foreach ( $userdata as $userdata_key => $userdata_field ) {
3201
+ $existing = $wpdb->get_row('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$uploadid.'\' AND property = \''.esc_sql($userdata_field['label']).'\' AND date_to = 0');
3202
+ if ($existing == null)
3203
+ $wpdb->insert($table_name2,
3204
+ array(
3205
+ 'uploadid' => $uploadid,
3206
+ 'property' => $userdata_field['label'],
3207
+ 'propkey' => $userdata_key,
3208
+ 'propvalue' => $userdata_field['value'],
3209
+ 'date_from' => $now_date,
3210
+ 'date_to' => 0
3211
+ ),
3212
+ array( '%s', '%s', '%d', '%s', '%s', '%s' ));
3213
+ }
3214
+ }
3215
+ }
3216
+ }
3217
+ //for rename or move action the $action variable is of the form:
3218
+ // $action = 'rename:'.$newfilepath; (for rename action)
3219
+ // $action = 'move:'.$newfilepath; (for move action)
3220
+ //in order to pass the new file path
3221
+ elseif ( substr($action, 0, 6) == 'rename' || substr($action, 0, 4) == 'move' ) {
3222
+ $cleanaction = ( substr($action, 0, 6) == 'rename' ? 'rename' : 'move' );
3223
+ //get new filepath
3224
+ $newfilepath = substr($action, strlen($cleanaction) + 1);
3225
+ $relativepath = wfu_path_abs2rel($newfilepath);
3226
+ // if ( substr($relativepath, 0, 1) != '/' ) $relativepath = '/'.$relativepath;
3227
+ //get stored file data from database without user data
3228
+ if ( $filerec == null ) $filerec = wfu_get_file_rec($filepath, false);
3229
+ //log action only if there are previous stored file data
3230
+ if ( $filerec != null ) {
3231
+ $now_date = date('Y-m-d H:i:s');
3232
+ //make previous record obsolete
3233
+ $wpdb->update($table_name1,
3234
+ array( 'date_to' => $now_date ),
3235
+ array( 'idlog' => $filerec->idlog ),
3236
+ array( '%s' ),
3237
+ array( '%d' )
3238
+ );
3239
+ //insert new rename record
3240
+ if ( $wpdb->insert($table_name1,
3241
+ array(
3242
+ 'userid' => $userid,
3243
+ 'uploaduserid' => $filerec->uploaduserid,
3244
+ 'uploadtime' => $filerec->uploadtime,
3245
+ 'sessionid' => $filerec->sessionid,
3246
+ 'filepath' => $relativepath,
3247
+ 'filehash' => $filerec->filehash,
3248
+ 'filesize' => $filerec->filesize,
3249
+ 'uploadid' => $filerec->uploadid,
3250
+ 'pageid' => $filerec->pageid,
3251
+ 'blogid' => $filerec->blogid,
3252
+ 'sid' => $filerec->sid,
3253
+ 'date_from' => $now_date,
3254
+ 'date_to' => 0,
3255
+ 'action' => $cleanaction,
3256
+ 'linkedto' => $filerec->idlog,
3257
+ 'filedata' => $filerec->filedata
3258
+ ),
3259
+ array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' ) ) !== false )
3260
+ $retid = $wpdb->insert_id;
3261
+ }
3262
+ }
3263
+ elseif ( $action == 'delete' ) {
3264
+ //get stored file data from database without user data
3265
+ if ( $filerec == null ) $filerec = wfu_get_file_rec($filepath, false);
3266
+ //log action only if there are previous stored file data
3267
+ if ( $filerec != null ) {
3268
+ $now_date = date('Y-m-d H:i:s');
3269
+ //make previous record obsolete
3270
+ $wpdb->update($table_name1,
3271
+ array( 'date_to' => $now_date ),
3272
+ array( 'idlog' => $filerec->idlog ),
3273
+ array( '%s' ),
3274
+ array( '%d' )
3275
+ );
3276
+ //insert new delete record
3277
+ if ( $wpdb->insert($table_name1,
3278
+ array(
3279
+ 'userid' => $userid,
3280
+ 'uploaduserid' => $filerec->uploaduserid,
3281
+ 'uploadtime' => $filerec->uploadtime,
3282
+ 'sessionid' => $filerec->sessionid,
3283
+ 'filepath' => $filerec->filepath,
3284
+ 'filehash' => $filerec->filehash,
3285
+ 'filesize' => $filerec->filesize,
3286
+ 'uploadid' => $filerec->uploadid,
3287
+ 'pageid' => $filerec->pageid,
3288
+ 'blogid' => $filerec->blogid,
3289
+ 'sid' => $filerec->sid,
3290
+ 'date_from' => $now_date,
3291
+ 'date_to' => $now_date,
3292
+ 'action' => 'delete',
3293
+ 'linkedto' => $filerec->idlog,
3294
+ 'filedata' => $filerec->filedata
3295
+ ),
3296
+ array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' )) != false )
3297
+ $retid = $wpdb->insert_id;
3298
+ }
3299
+ }
3300
+ elseif ( $action == 'download' ) {
3301
+ //get stored file data from database without user data
3302
+ $filerec = wfu_get_file_rec($filepath, false);
3303
+ //log action only if there are previous stored file data
3304
+ if ( $filerec != null ) {
3305
+ $now_date = date('Y-m-d H:i:s');
3306
+ //make previous record obsolete
3307
+ $wpdb->update($table_name1,
3308
+ array( 'date_to' => $now_date ),
3309
+ array( 'idlog' => $filerec->idlog ),
3310
+ array( '%s' ),
3311
+ array( '%d' )
3312
+ );
3313
+ //insert new download record
3314
+ if ( $wpdb->insert($table_name1,
3315
+ array(
3316
+ 'userid' => $userid,
3317
+ 'uploaduserid' => $filerec->uploaduserid,
3318
+ 'uploadtime' => $filerec->uploadtime,
3319
+ 'sessionid' => $filerec->sessionid,
3320
+ 'filepath' => $filerec->filepath,
3321
+ 'filehash' => $filerec->filehash,
3322
+ 'filesize' => $filerec->filesize,
3323
+ 'uploadid' => $filerec->uploadid,
3324
+ 'pageid' => $filerec->pageid,
3325
+ 'blogid' => $filerec->blogid,
3326
+ 'sid' => $filerec->sid,
3327
+ 'date_from' => $now_date,
3328
+ 'date_to' => 0,
3329
+ 'action' => 'download',
3330
+ 'linkedto' => $filerec->idlog,
3331
+ 'filedata' => $filerec->filedata
3332
+ ),
3333
+ array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' )) != false )
3334
+ $retid = $wpdb->insert_id;
3335
+ }
3336
+ }
3337
+ //for modify action the $action variable is of the form: $action = 'modify:'.$now_date; in order to pass the exact modify date
3338
+ elseif ( substr($action, 0, 6) == 'modify' ) {
3339
+ $now_date = substr($action, 7);
3340
+ //get stored file data from database without user data
3341
+ $filerec = wfu_get_file_rec($filepath, false);
3342
+ //log action only if there are previous stored file data
3343
+ if ( $filerec != null ) {
3344
+ //make previous record obsolete
3345
+ $wpdb->update($table_name1,
3346
+ array( 'date_to' => $now_date ),
3347
+ array( 'idlog' => $filerec->idlog ),
3348
+ array( '%s' ),
3349
+ array( '%d' )
3350
+ );
3351
+ //insert new modify record
3352
+ if ( $wpdb->insert($table_name1,
3353
+ array(
3354
+ 'userid' => $userid,
3355
+ 'uploaduserid' => $filerec->uploaduserid,
3356
+ 'uploadtime' => $filerec->uploadtime,
3357
+ 'sessionid' => $filerec->sessionid,
3358
+ 'filepath' => $filerec->filepath,
3359
+ 'filehash' => $filerec->filehash,
3360
+ 'filesize' => $filerec->filesize,
3361
+ 'uploadid' => $filerec->uploadid,
3362
+ 'pageid' => $filerec->pageid,
3363
+ 'blogid' => $filerec->blogid,
3364
+ 'sid' => $filerec->sid,
3365
+ 'date_from' => $now_date,
3366
+ 'date_to' => 0,
3367
+ 'action' => 'modify',
3368
+ 'linkedto' => $filerec->idlog,
3369
+ 'filedata' => $filerec->filedata
3370
+ ),
3371
+ array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' )) != false )
3372
+ $retid = $wpdb->insert_id;
3373
+ }
3374
+ }
3375
+ elseif ( substr($action, 0, 10) == 'changeuser' ) {
3376
+ $new_user = substr($action, 11);
3377
+ //get stored file data from database without user data
3378
+ $filerec = wfu_get_file_rec($filepath, false);
3379
+ //log action only if there are previous stored file data
3380
+ if ( $filerec != null ) {
3381
+ $now_date = date('Y-m-d H:i:s');
3382
+ //make previous record obsolete
3383
+ $wpdb->update($table_name1,
3384
+ array( 'date_to' => $now_date ),
3385
+ array( 'idlog' => $filerec->idlog ),
3386
+ array( '%s' ),
3387
+ array( '%d' )
3388
+ );
3389
+ //insert new modify record
3390
+ if ( $wpdb->insert($table_name1,
3391
+ array(
3392
+ 'userid' => $userid,
3393
+ 'uploaduserid' => $new_user,
3394
+ 'uploadtime' => $filerec->uploadtime,
3395
+ 'sessionid' => $filerec->sessionid,
3396
+ 'filepath' => $filerec->filepath,
3397
+ 'filehash' => $filerec->filehash,
3398
+ 'filesize' => $filerec->filesize,
3399
+ 'uploadid' => $filerec->uploadid,
3400
+ 'pageid' => $filerec->pageid,
3401
+ 'blogid' => $filerec->blogid,
3402
+ 'sid' => $filerec->sid,
3403
+ 'date_from' => $now_date,
3404
+ 'date_to' => 0,
3405
+ 'action' => 'changeuser',
3406
+ 'linkedto' => $filerec->idlog,
3407
+ 'filedata' => $filerec->filedata
3408
+ ),
3409
+ array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%s' )) != false )
3410
+ $retid = $wpdb->insert_id;
3411
+ }
3412
+ }
3413
+ elseif ( substr($action, 0, 5) == 'other' ) {
3414
+ $info = substr($action, 6);
3415
+ $now_date = date('Y-m-d H:i:s');
3416
+ //insert new other type record
3417
+ if ( $wpdb->insert($table_name1,
3418
+ array(
3419
+ 'userid' => $userid,
3420
+ 'uploaduserid' => -1,
3421
+ 'uploadtime' => 0,
3422
+ 'sessionid' => '',
3423
+ 'filepath' => $info,
3424
+ 'filehash' => '',
3425
+ 'filesize' => 0,
3426
+ 'uploadid' => '',
3427
+ 'pageid' => 0,
3428
+ 'blogid' => 0,
3429
+ 'sid' => '',
3430
+ 'date_from' => $now_date,
3431
+ 'date_to' => $now_date,
3432
+ 'action' => 'other',
3433
+ 'linkedto' => -1
3434
+ ),
3435
+ array( '%d', '%d', '%d', '%s', '%s', '%s', '%d', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d' )) != false )
3436
+ $retid = $wpdb->insert_id;
3437
+ }
3438
+ return $retid;
3439
+ }
3440
+
3441
+ /**
3442
+ * Revert Database Log Action.
3443
+ *
3444
+ * This function reverts an action that was recently added in the database. It
3445
+ * will also make effective the before-the-last one.
3446
+ *
3447
+ * @since 2.4.1
3448
+ *
3449
+ * @global object $wpdb The Wordpress database object.
3450
+ *
3451
+ * @param int $idlog The ID of the database record to revert.
3452
+ */
3453
+ function wfu_revert_log_action($idlog) {
3454
+ global $wpdb;
3455
+ $table_name1 = $wpdb->prefix . "wfu_log";
3456
+
3457
+ $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3458
+ if ( $filerec != null ) {
3459
+ $prevfilerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$filerec->linkedto);
3460
+ if ( $prevfilerec != null ) {
3461
+ $wpdb->delete($table_name1,
3462
+ array( 'idlog' => $filerec->idlog ),
3463
+ array( '%d' )
3464
+ );
3465
+ $wpdb->update($table_name1,
3466
+ array( 'date_to' => 0 ),
3467
+ array( 'idlog' => $prevfilerec->idlog ),
3468
+ array( '%s' ),
3469
+ array( '%d' )
3470
+ );
3471
+ }
3472
+ }
3473
+ }
3474
+
3475
+ /**
3476
+ * Get User Name by ID.
3477
+ *
3478
+ * This function retrieves a user's username by its ID. It will always return a
3479
+ * non-empty username, even if user is not found.
3480
+ *
3481
+ * @since 2.4.1
3482
+ *
3483
+ * @redeclarable
3484
+ *
3485
+ * @param int $id The ID of the user.
3486
+ *
3487
+ * @return string The username.
3488
+ */
3489
+ function wfu_get_username_by_id($id) {
3490
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3491
+ $user = get_user_by('id', $id);
3492
+ if ( $user == false && $id > 0 ) $username = 'unknown';
3493
+ elseif ( $user == false && $id == -999 ) $username = 'system';
3494
+ elseif ( $user == false ) $username = 'guest';
3495
+ else $username = $user->user_login;
3496
+ return $username;
3497
+ }
3498
+
3499
+ /**
3500
+ * Get Number of Unread Files.
3501
+ *
3502
+ * This function retrieves the number of uploaded files that have not been read
3503
+ * by the administrator (admin has not opened Uploaded Files page in Dashboard
3504
+ * to review them).
3505
+ *
3506
+ * @since 4.7.0
3507
+ *
3508
+ * @global object $wpdb The Wordpress database object.
3509
+ *
3510
+ * @redeclarable
3511
+ *
3512
+ * @return int The number of unread files.
3513
+ */
3514
+ function wfu_get_unread_files_count() {
3515
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3516
+ global $wpdb;
3517
+ $table_name1 = $wpdb->prefix . "wfu_log";
3518
+
3519
+ //get the last idlog read from options; create the option if it does not
3520
+ //exist pointing to the currently last idlog
3521
+ $last_idlog = get_option( "wordpress_file_upload_last_idlog" );
3522
+ if ( $last_idlog === false ) {
3523
+ $latest_idlog = $wpdb->get_var('SELECT MAX(idlog) FROM '.$table_name1);
3524
+ $last_idlog = array( 'pre' => $latest_idlog, 'post' => $latest_idlog, 'time' => time() );
3525
+ update_option( "wordpress_file_upload_last_idlog", $last_idlog );
3526
+ }
3527
+ $limit = (int)WFU_VAR("WFU_UPLOADEDFILES_RESET_TIME");
3528
+ $unread_files_count = 0;
3529
+ if ( $limit == -1 || time() > $last_idlog["time"] + $limit ) $unread_files_count = wfu_get_new_files_count($last_idlog["post"]);
3530
+ else $unread_files_count = wfu_get_new_files_count($last_idlog["pre"]);
3531
+
3532
+ return $unread_files_count;
3533
+ }
3534
+
3535
+ /**
3536
+ * Get Number of New Uploaded Files.
3537
+ *
3538
+ * This function retrieves the number of newly uploaded files by counting how
3539
+ * many where uploaded after a specific database record ID.
3540
+ *
3541
+ * @since 4.8.0
3542
+ *
3543
+ * @global object $wpdb The Wordpress database object.
3544
+ *
3545
+ * @redeclarable
3546
+ *
3547
+ * @param int $last_idlog The database record ID which is the base for counting.
3548
+ *
3549
+ * @return int The number of new uploaded files.
3550
+ */
3551
+ function wfu_get_new_files_count($last_idlog) {
3552
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3553
+ global $wpdb;
3554
+ $table_name1 = $wpdb->prefix . "wfu_log";
3555
+ return $wpdb->get_var('SELECT COUNT(idlog) FROM '.$table_name1.' WHERE action = \'upload\' AND idlog > '.(int)$last_idlog);
3556
+ }
3557
+
3558
+ /**
3559
+ * Decode Raw File Transfers Log Data.
3560
+ *
3561
+ * This function converts raw file transfers log data stored in filedata field
3562
+ * of a file's database record into a structured array.
3563
+ *
3564
+ * @since 4.9.0
3565
+ *
3566
+ * @redeclarable
3567
+ *
3568
+ * @param string $data The raw log data.
3569
+ *
3570
+ * @return array {
3571
+ * An array of file transfers log information.
3572
+ *
3573
+ * $type string $service The cloud service used for the file transfer.
3574
+ * $type bool $transferred True if the file transfer was successful.
3575
+ * $type string $error Error message if the file transfer failed.
3576
+ * $type string $destination The destination path of the transfer.
3577
+ * $type string $new_filename The new file name of the transferred file.
3578
+ * }
3579
+ */
3580
+ function wfu_read_log_data($data) {
3581
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
3582
+ $ret['service'] = "";
3583
+ $ret['transferred'] = "";
3584
+ $ret['error'] = "";
3585
+ $ret['destination'] = "";
3586
+ $ret['new_filename'] = "";
3587
+ if ( substr($data, 0, 5) == "json:" ) {
3588
+ $logdata = json_decode(substr($data, 5), true);
3589
+ $ret['service'] = $logdata["service"];
3590
+ $ret['transferred'] = $logdata["transferred"];
3591
+ $ret['error'] = $logdata["error"];
3592
+ $ret['destination'] = $logdata["destination"];
3593
+ $ret['new_filename'] = $logdata["new_filename"];
3594
+ }
3595
+ else list($ret['service'], $ret['destination']) = explode("|", $data);
3596
+
3597
+ return $ret;
3598
+ }
3599
+
3600
+ /**
3601
+ * Get Database File Record From File Path.
3602
+ *
3603
+ * This function gets the most current database record of an uploaded file from
3604
+ * its path and also includes any userdata.
3605
+ *
3606
+ * @since 2.4.1
3607
+ *
3608
+ * @global object $wpdb The Wordpress database object.
3609
+ *
3610
+ * @param string $filepath The path of the file.
3611
+ * @param bool $include_userdata Include any userdata information in the
3612
+ * returned record.
3613
+ *
3614
+ * @return object|null The database object of the file, or null if it is not
3615
+ * found.
3616
+ */
3617
+ function wfu_get_file_rec($filepath, $include_userdata) {
3618
+ global $wpdb;
3619
+ $table_name1 = $wpdb->prefix . "wfu_log";
3620
+ $table_name2 = $wpdb->prefix . "wfu_userdata";
3621
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
3622
+
3623
+ if ( !wfu_file_exists($filepath, "wfu_get_file_rec") ) return null;
3624
+
3625
+ $relativepath = wfu_path_abs2rel($filepath);
3626
+ // if ( substr($relativepath, 0, 1) != '/' ) $relativepath = '/'.$relativepath;
3627
+ //if file hash is enabled, then search file based on its path and hash, otherwise find file based on its path and size
3628
+ if ( isset($plugin_options['hashfiles']) && $plugin_options['hashfiles'] == '1' ) {
3629
+ $filehash = wfu_md5_file($filepath, "wfu_get_file_rec");
3630
+ $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE filepath = \''.esc_sql($relativepath).'\' AND filehash = \''.$filehash.'\' AND date_to = 0 ORDER BY date_from DESC');
3631
+ }
3632
+ else {
3633
+ $stat = wfu_stat($filepath, "wfu_get_file_rec");
3634
+ $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE filepath = \''.esc_sql($relativepath).'\' AND filesize = '.$stat['size'].' AND date_to = 0 ORDER BY date_from DESC');
3635
+ }
3636
+ //get user data
3637
+ if ( $filerec != null && $include_userdata ) {
3638
+ $filerec->userdata = null;
3639
+ if ( $filerec->uploadid != '' ) {
3640
+ $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
3641
+ }
3642
+ }
3643
+ return $filerec;
3644
+ }
3645
+
3646
+ /**
3647
+ * Get Valid Files From a List of Database Records.
3648
+ *
3649
+ * This function checks which records in a given list of database records of
3650
+ * uploaded files contain valid files and returns their file paths.
3651
+ *
3652
+ * @since 4.9.1
3653
+ *
3654
+ * @param array $recs An array of database records of uploaded files.
3655
+ *
3656
+ * @return array An array of file paths of valid files.
3657
+ */
3658
+ function wfu_get_valid_affected_files($recs) {
3659
+ $valid_affected_files = array();
3660
+ $files_checked = array();
3661
+ foreach ($recs as $rec)
3662
+ if ( $latestrec = wfu_get_latest_rec_from_id($rec->idlog) ) {
3663
+ $file = wfu_path_rel2abs($latestrec->filepath);
3664
+ if ( !in_array($file, $files_checked) ) {
3665
+ if ( wfu_file_exists($file, "wfu_get_valid_affected_files") ) array_push($valid_affected_files, $file);
3666
+ array_push($files_checked, $file);
3667
+ }
3668
+ }
3669
+
3670
+ return $valid_affected_files;
3671
+ }
3672
+
3673
+ /**
3674
+ * Get Database File Record From Record ID.
3675
+ *
3676
+ * This function gets the database record of an uploaded file from its record ID
3677
+ * and also includes any userdata.
3678
+ *
3679
+ * @since 3.9.4
3680
+ *
3681
+ * @global object $wpdb The Wordpress database object.
3682
+ *
3683
+ * @param int $idlog The database record ID.
3684
+ * @param bool $include_userdata Optional. Include any userdata information in
3685
+ * the returned record.
3686
+ *
3687
+ * @return object|null The database object of the file, or null if it is not
3688
+ * found.
3689
+ */
3690
+ function wfu_get_file_rec_from_id($idlog, $include_userdata = false) {
3691
+ global $wpdb;
3692
+ $table_name1 = $wpdb->prefix . "wfu_log";
3693
+ $table_name2 = $wpdb->prefix . "wfu_userdata";
3694
+
3695
+ $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3696
+ if ( $filerec != null && $include_userdata ) {
3697
+ $filerec->userdata = null;
3698
+ if ( $filerec->uploadid != '' ) {
3699
+ $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
3700
+ }
3701
+ }
3702
+
3703
+ return $filerec;
3704
+ }
3705
+
3706
+ /**
3707
+ * Get Userdata of Uploaded File by Database Record ID.
3708
+ *
3709
+ * This function gets the userdata (if any) of an uploaded file from its
3710
+ * database record ID.
3711
+ *
3712
+ * @since 4.6.0
3713
+ *
3714
+ * @param int $idlog The database record ID.
3715
+ *
3716
+ * @return array {
3717
+ * An array of userdata.
3718
+ *
3719
+ * @type $arrayitem {
3720
+ * An individual userdata field.
3721
+ *
3722
+ * @type string $property The title of the userdata field.
3723
+ * @type string $value The value entered by the user in the field.
3724
+ * }
3725
+ * }
3726
+ */
3727
+ function wfu_get_userdata_from_id($idlog) {
3728
+ $userdata = array();
3729
+ $filerec = wfu_get_file_rec_from_id($idlog, true);
3730
+ if ( $filerec != null && $filerec->userdata != null )
3731
+ foreach ( $filerec->userdata as $item ) {
3732
+ $arrayitem = array(
3733
+ "property" => $item->property,
3734
+ "value" => $item->propvalue
3735
+ );
3736
+ array_push($userdata, $arrayitem);
3737
+ }
3738
+
3739
+ return $userdata;
3740
+ }
3741
+
3742
+ /**
3743
+ * Get Oldest Database Record From Unique ID.
3744
+ *
3745
+ * Every file upload has a unique ID. This unique ID remains the same for any
3746
+ * consecutive operations that happen on the file (renaming, transfer, deletion
3747
+ * etc.). This function gets the oldest (first) record related to this unique
3748
+ * ID, which is usually an 'upload' or 'include' action.
3749
+ *
3750
+ * @since 4.10.0
3751
+ *
3752
+ * @global object $wpdb The Wordpress database object.
3753
+ *
3754
+ * @param string $uniqueid The unique ID of the upload.
3755
+ *
3756
+ * @return object|null The oldest database record, or null if not found.
3757
+ */
3758
+ function wfu_get_oldestrec_from_uniqueid($uniqueid) {
3759
+ global $wpdb;
3760
+ $table_name1 = $wpdb->prefix . "wfu_log";
3761
+ $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE idlog IN (SELECT MIN(idlog) FROM '.$table_name1.' WHERE uploadid = \''.$uniqueid.'\')');
3762
+ if ( $filerecs == null ) return null;
3763
+ if ( count($filerecs) > 0 ) return $filerecs[0];
3764
+ else return null;
3765
+ }
3766
+
3767
+ /**
3768
+ * Get Latest Database Record From Record ID.
3769
+ *
3770
+ * This function gets the most recend (latest) record of a linked series of
3771
+ * database upload records having the same unique ID. Every record is linked to
3772
+ * its newer one through 'linkedto' field.
3773
+ *
3774
+ * @since 4.2.0
3775
+ *
3776
+ * @global object $wpdb The Wordpress database object.
3777
+ *
3778
+ * @param int $idlog The database record ID.
3779
+ *
3780
+ * @return object|null The latest database record, or null if not found.
3781
+ */
3782
+ function wfu_get_latest_rec_from_id($idlog) {
3783
+ global $wpdb;
3784
+ $table_name1 = $wpdb->prefix . "wfu_log";
3785
+ $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3786
+ while ( $filerec != null && $filerec->date_to != "0000-00-00 00:00:00" )
3787
+ $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE linkedto = '.$filerec->idlog);
3788
+
3789
+ return $filerec;
3790
+ }
3791
+
3792
+ /**
3793
+ * Get Newer Linked Database Records From Record ID.
3794
+ *
3795
+ * This function gets the newer records of a linked series of database upload
3796
+ * records having the same unique ID. Every record is linked to its newer one
3797
+ * through 'linkedto' field.
3798
+ *
3799
+ * @since 4.7.0
3800
+ *
3801
+ * @global object $wpdb The Wordpress database object.
3802
+ *
3803
+ * @param int $idlog The database record ID.
3804
+ *
3805
+ * @return array An array of newer linked database records.
3806
+ */
3807
+ function wfu_get_rec_new_history($idlog) {
3808
+ global $wpdb;
3809
+ $table_name1 = $wpdb->prefix . "wfu_log";
3810
+ $filerecs = array();
3811
+ $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3812
+ while ( $filerec != null ) {
3813
+ array_push($filerecs, $filerec);
3814
+ $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE linkedto = '.$filerec->idlog);
3815
+ }
3816
+
3817
+ return $filerecs;
3818
+ }
3819
+
3820
+ /**
3821
+ * Get Older Linked Database Records From Record ID.
3822
+ *
3823
+ * This function gets the older records of a linked series of database upload
3824
+ * records having the same unique ID. Every record is linked to its newer one
3825
+ * through 'linkedto' field.
3826
+ *
3827
+ * @since 4.7.0
3828
+ *
3829
+ * @global object $wpdb The Wordpress database object.
3830
+ *
3831
+ * @param int $idlog The database record ID.
3832
+ *
3833
+ * @return array An array of older linked database records.
3834
+ */
3835
+ function wfu_get_rec_old_history($idlog) {
3836
+ global $wpdb;
3837
+ $table_name1 = $wpdb->prefix . "wfu_log";
3838
+ $filerecs = array();
3839
+ $filerec = $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$idlog);
3840
+ while ( $filerec != null ) {
3841
+ array_push($filerecs, $filerec);
3842
+ $filerec = ( $filerec->linkedto > 0 ? $wpdb->get_row('SELECT * FROM '.$table_name1.' WHERE idlog = '.$filerec->linkedto) : null );
3843
+ }
3844
+
3845
+ return $filerecs;
3846
+ }
3847
+
3848
+ /**
3849
+ * Get Latest Filedata Properties From Database Record ID
3850
+ *
3851
+ * This function uses an uploaded file's database record ID to return the
3852
+ * filedata property of the corresponding record of the file in the database
3853
+ * holding data about its transfer to a service account like Dropbox, provided
3854
+ * that this record is still valid. If the record does not exist or exists but
3855
+ * it is absolete, then the function returns null, otherwise it returns an
3856
+ * array.
3857
+ *
3858
+ * The [$service]["filepath"] item of the array is set to the final $filepath
3859
+ * of the file, in case that the original filename was renamed.
3860
+ *
3861
+ * @since 4.2.0
3862
+ *
3863
+ * @param int $idlog Database record ID of the uploaded file.
3864
+ * @param bool $is_new Optional. It must be true if the function is called
3865
+ * during addition of a new file.
3866
+ *
3867
+ * @return array|null Returns the filedata array or null if it is not found.
3868
+ */
3869
+ function wfu_get_latest_filedata_from_id($idlog, $is_new = false) {
3870
+ //get latest database record of file, if it is still valid
3871
+ $filerec = wfu_get_latest_rec_from_id($idlog);
3872
+ //return null if the record does not exist or it is obsolete
3873
+ if ( $filerec == null ) return null;
3874
+
3875
+ return wfu_get_filedata_from_rec($filerec, $is_new, true, false);
3876
+ }
3877
+
3878
+ /**
3879
+ * Get Filedata Properties From File Path
3880
+ *
3881
+ * This function uses an uploaded file's path to return the filedata property of
3882
+ * the corresponding record of the file in the database holding data about its
3883
+ * transfer to a service account like Dropbox, provided that this record is
3884
+ * still valid.
3885
+ *
3886
+ * @since 4.2.0
3887
+ *
3888
+ * @param string $filepath The path of the uploaded file.
3889
+ * @param bool $include_general_data Optional. Determines whether general upload
3890
+ * data will be included in the returned filedata structure.
3891
+ *
3892
+ * @return array|null Returns the filedata array or null if it is not found.
3893
+ */
3894
+ function wfu_get_filedata($filepath, $include_general_data = false) {
3895
+ $filerec = wfu_get_file_rec($filepath, false);
3896
+ if ( $filerec == null ) return null;
3897
+
3898
+ return wfu_get_filedata_from_rec($filerec, true, false, $include_general_data);
3899
+ }
3900
+
3901
+ /**
3902
+ * Get Filedata Properties From Database Record
3903
+ *
3904
+ * This function uses an uploaded file's database record to return the filedata
3905
+ * property of the corresponding record of the file in the database holding data
3906
+ * about its transfer to a service account like Dropbox, provided that this
3907
+ * record is still valid.
3908
+ *
3909
+ * @since 4.3.0
3910
+ *
3911
+ * @param object $filerec The database record of the uploaded file.
3912
+ * @param bool $is_new Optional. It must be true if the function is called
3913
+ * during addition of a new file.
3914
+ * @param bool $update_transfer Optional. Update filepath property in filedata
3915
+ * of "transfer" type, if service records exist.
3916
+ * @param bool $include_general_data Optional. Determines whether general upload
3917
+ * data will be included in the returned filedata structure.
3918
+ *
3919
+ * @return array|null Returns the filedata array or null if it is not found.
3920
+ */
3921
+ function wfu_get_filedata_from_rec($filerec, $is_new = false, $update_transfer = false, $include_general_data = false) {
3922
+ //return filedata, if it does not exist and we do not want to create a new
3923
+ //filedata structure return null, otherwise return an empty array
3924
+ if ( !isset($filerec->filedata) || is_null($filerec->filedata) ) $filedata = ( $is_new ? array() : null );
3925
+ else {
3926
+ $filedata = wfu_decode_array_from_string($filerec->filedata);
3927
+ if ( !is_array($filedata) ) $filedata = ( $is_new ? array() : null );
3928
+ }
3929
+ if ( !is_null($filedata) ) {
3930
+ //update filepath property in filedata of "transfer" type, if service
3931
+ //records exist
3932
+ if ( $update_transfer ) {
3933
+ foreach ( $filedata as $key => $data )
3934
+ if ( !isset($data["type"]) || $data["type"] == "transfer" )
3935
+ $filedata[$key]["filepath"] = $filerec->filepath;
3936
+ }
3937
+ //add idlog in filedata if $include_general_data is true
3938
+ if ( $include_general_data )
3939
+ $filedata["general"] = array(
3940
+ "type" => "data",
3941
+ "idlog" => $filerec->idlog
3942
+ );
3943
+ }
3944
+
3945
+ return $filedata;
3946
+ }
3947
+
3948
+ /**
3949
+ * Save Filedata To File Database Record
3950
+ *
3951
+ * This function updates the filedata field of the database record of an
3952
+ * uploaded file.
3953
+ *
3954
+ * @since 4.2.0
3955
+ *
3956
+ * @global object $wpdb The Wordpress database object.
3957
+ *
3958
+ * @param int $idlog The database record ID of the uploaded file to be updated.
3959
+ * @param array $filedata The new filedata structure to store.
3960
+ * @param bool $store_in_latest_rec Optional. Store in the latest linked
3961
+ * database record and not the current one.
3962
+ *
3963
+ * @return bool|int Returns false if errors, or the number of rows affected if
3964
+ * successful.
3965
+ */
3966
+ function wfu_save_filedata_from_id($idlog, $filedata, $store_in_latest_rec = true) {
3967
+ global $wpdb;
3968
+ $table_name1 = $wpdb->prefix . "wfu_log";
3969
+ if ( $store_in_latest_rec ) {
3970
+ $latestrec = wfu_get_latest_rec_from_id($idlog);
3971
+ $idlog = $latestrec->idlog;
3972
+ }
3973
+ return $wpdb->update($table_name1, array( 'filedata' => wfu_encode_array_to_string($filedata) ), array( 'idlog' => $idlog ), array( '%s' ), array( '%d' ));
3974
+ }
3975
+
3976
+ /**
3977
+ * Get Userdata of Uploaded File From Database Record.
3978
+ *
3979
+ * This function gets the database record of an uploaded file from its database
3980
+ * record.
3981
+ *
3982
+ * @since 4.7.0
3983
+ *
3984
+ * @see wfu_get_userdata_from_id() For more information on the response array
3985
+ * format.
3986
+ *
3987
+ * @global object $wpdb The Wordpress database object.
3988
+ *
3989
+ * @param object $filerec The database record of the uploaded file.
3990
+ *
3991
+ * @return array An array of userdata.
3992
+ */
3993
+ function wfu_get_userdata_from_rec($filerec) {
3994
+ global $wpdb;
3995
+ $table_name2 = $wpdb->prefix . "wfu_userdata";
3996
+
3997
+ $userdata = array();
3998
+ if ( $filerec->uploadid != '' ) {
3999
+ $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
4000
+ if ( $filerec->userdata != null )
4001
+ foreach ( $filerec->userdata as $item ) {
4002
+ array_push($userdata, $item);
4003
+ }
4004
+ }
4005
+
4006
+ return $userdata;
4007
+ }
4008
+
4009
+ /**
4010
+ * Get Userdata of Uploaded File From Unique ID.
4011
+ *
4012
+ * This function gets the database record of an uploaded file from the unique ID
4013
+ * of the upload.
4014
+ *
4015
+ * @since 3.11.0
4016
+ *
4017
+ * @global object $wpdb The Wordpress database object.
4018
+ *
4019
+ * @param string $uploadid The unique ID of the upload.
4020
+ *
4021
+ * @return object|null A userdata database record or null if not found.
4022
+ */
4023
+ function wfu_get_userdata_from_uploadid($uploadid) {
4024
+ global $wpdb;
4025
+ $table_name2 = $wpdb->prefix . "wfu_userdata";
4026
+ $userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$uploadid.'\' AND date_to = 0 ORDER BY propkey');
4027
+
4028
+ return $userdata;
4029
+ }
4030
+
4031
+ /**
4032
+ * Reassign File Hashes.
4033
+ *
4034
+ * The plugin calculates md5 hashes for all uploaded files, upon selection, to
4035
+ * verify later if the files have changed or not. This function reassignes the
4036
+ * hashes for all valid uploaded files. This function may take a lot of time
4037
+ * depending on the number and size of the uploaded files.
4038
+ *
4039
+ * @since 2.4.1
4040
+ *
4041
+ * @global object $wpdb The Wordpress database object.
4042
+ */
4043
+ function wfu_reassign_hashes() {
4044
+ global $wpdb;
4045
+ $table_name1 = $wpdb->prefix . "wfu_log";
4046
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
4047
+ if ( $plugin_options['hashfiles'] == '1' ) {
4048
+ $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE filehash = \'\' AND date_to = 0');
4049
+ foreach( $filerecs as $filerec ) {
4050
+ //calculate full file path
4051
+ $filepath = wfu_path_rel2abs($filerec->filepath);
4052
+ if ( wfu_file_exists($filepath, "wfu_reassign_hashes") ) {
4053
+ $filehash = wfu_md5_file($filepath, "wfu_reassign_hashes");
4054
+ $wpdb->update($table_name1,
4055
+ array( 'filehash' => $filehash ),
4056
+ array( 'idlog' => $filerec->idlog ),
4057
+ array( '%s' ),
4058
+ array( '%d' )
4059
+ );
4060
+ }
4061
+ }
4062
+ }
4063
+ }
4064
+
4065
+ /**
4066
+ * Make Uploaded File Database Record Obsolete.
4067
+ *
4068
+ * This function makes a database record of an uploaded file obsolete. This
4069
+ * means that the file is considered not valid anymore. Any related thumbnails
4070
+ * are deleted.
4071
+ *
4072
+ * @since 3.11.0
4073
+ *
4074
+ * @global object $wpdb The Wordpress database object.
4075
+ *
4076
+ * @redeclarable
4077
+ *
4078
+ * @param object $filerec The database record to make obsolete.
4079
+ *
4080
+ * @return bool|int Returns false if errors, or the number of rows affected if
4081
+ * successful.
4082
+ */
4083
+ function wfu_make_rec_obsolete($filerec) {
4084
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
4085
+ global $wpdb;
4086
+ $table_name1 = $wpdb->prefix . "wfu_log";
4087
+ $filedata = wfu_get_filedata_from_rec($filerec, true);
4088
+ //update db record accordingly
4089
+ $wpdb->update($table_name1,
4090
+ array( 'date_to' => date('Y-m-d H:i:s'), 'filedata' => wfu_encode_array_to_string($filedata) ),
4091
+ array( 'idlog' => $filerec->idlog ),
4092
+ array( '%s', '%s' ),
4093
+ array( '%d' )
4094
+ );
4095
+ }
4096
+
4097
+ /**
4098
+ * Synchronize Plugin's Database.
4099
+ *
4100
+ * This function updates database to reflect the current status of files.
4101
+ *
4102
+ * @since 2.4.1
4103
+ *
4104
+ * @global object $wpdb The Wordpress database object.
4105
+ *
4106
+ * @redeclarable
4107
+ *
4108
+ * @return number The number of obsolete records found.
4109
+ */
4110
+ function wfu_sync_database() {
4111
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
4112
+ global $wpdb;
4113
+ $table_name1 = $wpdb->prefix . "wfu_log";
4114
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
4115
+
4116
+ $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action <> \'other\' AND action <> \'datasubmit\' AND date_to = 0');
4117
+ $obsolete_count = 0;
4118
+ foreach( $filerecs as $filerec ) {
4119
+ $obsolete = true;
4120
+ //calculate full file path
4121
+ $filepath = wfu_path_rel2abs($filerec->filepath);
4122
+ if ( wfu_file_exists($filepath, "wfu_sync_database") ) {
4123
+ if ( $plugin_options['hashfiles'] == '1' ) {
4124
+ $filehash = wfu_md5_file($filepath, "wfu_sync_database");
4125
+ if ( $filehash == $filerec->filehash ) $obsolete = false;
4126
+ }
4127
+ else {
4128
+ $filesize = wfu_filesize($filepath, "wfu_sync_database");
4129
+ if ( $filesize == $filerec->filesize ) $obsolete = false;
4130
+ }
4131
+ }
4132
+ if ( $obsolete ) {
4133
+ wfu_make_rec_obsolete($filerec);
4134
+ $obsolete_count ++;
4135
+ }
4136
+ }
4137
+ return $obsolete_count;
4138
+ }
4139
+
4140
+ /**
4141
+ * Get Uploaded File Database Records of Specific User.
4142
+ *
4143
+ * This function is used the retrieve the files uploaded by a specific user by
4144
+ * returning all the valid uploaded files' database records. If the user ID
4145
+ * provided starts with 'guest' then this means that the user is a guest and
4146
+ * retrieval will be done based on the session ID of the session that was
4147
+ * generated between the user's browser and the website when the user uploaded
4148
+ * files. This function will check if there are obsolete records. It will also
4149
+ * return any additional user data.
4150
+ *
4151
+ * @since 3.0.0
4152
+ *
4153
+ * @global object $wpdb The Wordpress database object.
4154
+ *
4155
+ * @param int|string $userid The user ID. If the user is a guest, it must be a
4156
+ * string starting with 'guest' and then including the session ID.
4157
+ *
4158
+ * @return array An array of user's database records of uploaded files.
4159
+ */
4160
+ function wfu_get_recs_of_user($userid) {
4161
+ global $wpdb;
4162
+ $table_name1 = $wpdb->prefix . "wfu_log";
4163
+ $table_name2 = $wpdb->prefix . "wfu_userdata";
4164
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
4165
+
4166
+ //if $userid starts with 'guest' then retrieval of records is done using sessionid and uploaduserid is zero (for guests)
4167
+ if ( substr($userid, 0, 5) == 'guest' )
4168
+ $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action <> \'other\' AND action <> \'datasubmit\' AND uploaduserid = 0 AND sessionid = \''.substr($userid, 5).'\' AND date_to = 0');
4169
+ else
4170
+ $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action <> \'other\' AND action <> \'datasubmit\' AND uploaduserid = '.$userid.' AND date_to = 0');
4171
+ $out = array();
4172
+ foreach( $filerecs as $filerec ) {
4173
+ $obsolete = true;
4174
+ //calculate full file path
4175
+ $filepath = wfu_path_rel2abs($filerec->filepath);
4176
+ if ( wfu_file_exists($filepath, "wfu_get_recs_of_user") ) {
4177
+ if ( $plugin_options['hashfiles'] == '1' ) {
4178
+ $filehash = wfu_md5_file($filepath, "wfu_get_recs_of_user");
4179
+ if ( $filehash == $filerec->filehash ) $obsolete = false;
4180
+ }
4181
+ else {
4182
+ $filesize = wfu_filesize($filepath, "wfu_get_recs_of_user");
4183
+ if ( $filesize == $filerec->filesize ) $obsolete = false;
4184
+ }
4185
+ }
4186
+ if ( $obsolete ) {
4187
+ wfu_make_rec_obsolete($filerec);
4188
+ }
4189
+ else {
4190
+ $filerec->userdata = null;
4191
+ if ( $filerec->uploadid != '' )
4192
+ $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
4193
+ array_push($out, $filerec);
4194
+ }
4195
+ }
4196
+
4197
+ return $out;
4198
+ }
4199
+
4200
+ /**
4201
+ * Basic Check Whether File is Remote.
4202
+ *
4203
+ * This function does a basic check whether the file is remote (it is stored in
4204
+ * a cloud service). The absolute file path of a remote file starts with
4205
+ * 'service:'.
4206
+ *
4207
+ * @since 4.16.0
4208
+ *
4209
+ * @param string $abs_filepath The absolute file path of the file.
4210
+ *
4211
+ * @return bool Returns true if the file is remote, false otherwise.
4212
+ */
4213
+ function wfu_check_file_remote_basic($abs_filepath) {
4214
+ return ( substr($abs_filepath, 0, 7) == "remote:" );
4215
+ }
4216
+
4217
+ /**
4218
+ * Get Filtered Uploaded Files Database Records.
4219
+ *
4220
+ * This function gets a list of database records of uploaded files based on a
4221
+ * list of filters. This function will check if there are obsolete records. It
4222
+ * will also return any additional user data.
4223
+ *
4224
+ * @since 3.2.1
4225
+ *
4226
+ * @global object $wpdb The Wordpress database object.
4227
+ *
4228
+ * @redeclarable
4229
+ *
4230
+ * @param array $filter An array of filters to apply.
4231
+ *
4232
+ * @return array An array of matched database records of uploaded files.
4233
+ */
4234
+ function wfu_get_filtered_recs($filter) {
4235
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
4236
+ global $wpdb;
4237
+ $table_name1 = $wpdb->prefix . "wfu_log";
4238
+ $table_name2 = $wpdb->prefix . "wfu_userdata";
4239
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
4240
+
4241
+ $queries = array();
4242
+ // add default filters
4243
+ array_push($queries, 'a.action <> \'other\' AND a.action <> \'datasubmit\'');
4244
+ array_push($queries, 'a.date_to = 0');
4245
+ // construct user filter
4246
+ if ( isset($filter['user']) ) {
4247
+ if ( $filter['user']['all'] ) {
4248
+ if ( $filter['user']['guests'] ) $query = 'a.uploaduserid >= 0';
4249
+ else $query = 'a.uploaduserid > 0';
4250
+ }
4251
+ elseif ( count($filter['user']['ids']) == 1 && substr($filter['user']['ids'][0], 0, 5) == 'guest' )
4252
+ $query = 'a.uploaduserid = 0 AND a.sessionid = \''.substr($filter['user']['ids'][0], 5).'\'';
4253
+ else {
4254
+ if ( $filter['user']['guests'] ) array_push($filter['user']['ids'], '0');
4255
+ if ( count($filter['user']['ids']) == 1 ) $query = 'a.uploaduserid = '.$filter['user']['ids'][0];
4256
+ else $query = 'a.uploaduserid in ('.implode(",",$filter['user']['ids']).')';
4257
+ }
4258
+ array_push($queries, $query);
4259
+ }
4260
+ // construct size filter
4261
+ if ( isset($filter['size']) ) {
4262
+ if ( isset($filter['size']['lower']) && isset($filter['size']['upper']) )
4263
+ $query = 'a.filesize > '.$filter['size']['lower'].' AND a.filesize < '.$filter['size']['upper'];
4264
+ elseif ( isset($filter['size']['lower']) ) $query = 'a.filesize > '.$filter['size']['lower'];
4265
+ else $query = 'a.filesize < '.$filter['size']['upper'];
4266
+ array_push($queries, $query);
4267
+ }
4268
+ // construct date filter
4269
+ if ( isset($filter['date']) ) {
4270
+ if ( isset($filter['date']['lower']) && isset($filter['date']['upper']) )
4271
+ $query = 'a.uploadtime > '.$filter['date']['lower'].' AND a.uploadtime < '.$filter['date']['upper'];
4272
+ elseif ( isset($filter['date']['lower']) ) $query = 'a.uploadtime > '.$filter['date']['lower'];
4273
+ else $query = 'a.uploadtime < '.$filter['date']['upper'];
4274
+ array_push($queries, $query);
4275
+ }
4276
+ // construct file pattern filter
4277
+ if ( isset($filter['pattern']) ) {
4278
+ $query = 'a.filepath REGEXP \''.wfu_upload_plugin_wildcard_to_mysqlregexp($filter['pattern']).'\'';
4279
+ array_push($queries, $query);
4280
+ }
4281
+ // construct page/post filter
4282
+ if ( isset($filter['post']) ) {
4283
+ if ( count($filter['post']['ids']) == 1 ) $query = 'a.pageid = '.$filter['post']['ids'][0];
4284
+ else $query = 'a.pageid in ('.implode(",",$filter['post']['ids']).')';
4285
+ array_push($queries, $query);
4286
+ }
4287
+ // construct blog filter
4288
+ if ( isset($filter['blog']) ) {
4289
+ if ( count($filter['blog']['ids']) == 1 ) $query = 'a.blogid = '.$filter['blog']['ids'][0];
4290
+ else $query = 'a.blogid in ('.implode(",",$filter['blog']['ids']).')';
4291
+ array_push($queries, $query);
4292
+ }
4293
+ // construct userdata filter
4294
+ if ( isset($filter['userdata']) ) {
4295
+ if ( $filter['userdata']['criterion'] == "equal to" ) $valuecriterion = 'propvalue = \''.esc_sql($filter['userdata']['value']).'\'';
4296
+ elseif ( $filter['userdata']['criterion'] == "starts with" ) $valuecriterion = 'propvalue LIKE \''.esc_sql($filter['userdata']['value']).'%\'';
4297
+ elseif ( $filter['userdata']['criterion'] == "ends with" ) $valuecriterion = 'propvalue LIKE \'%'.esc_sql($filter['userdata']['value']).'\'';
4298
+ elseif ( $filter['userdata']['criterion'] == "contains" ) $valuecriterion = 'propvalue LIKE \'%'.esc_sql($filter['userdata']['value']).'%\'';
4299
+ elseif ( $filter['userdata']['criterion'] == "not equal to" ) $valuecriterion = 'propvalue <> \''.esc_sql($filter['userdata']['value']).'\'';
4300
+ elseif ( $filter['userdata']['criterion'] == "does not start with" ) $valuecriterion = 'propvalue NOT LIKE \''.esc_sql($filter['userdata']['value']).'%\'';
4301
+ elseif ( $filter['userdata']['criterion'] == "does not end with" ) $valuecriterion = 'propvalue NOT LIKE \'%'.esc_sql($filter['userdata']['value']).'\'';
4302
+ elseif ( $filter['userdata']['criterion'] == "does not contain" ) $valuecriterion = 'propvalue NOT LIKE \'%'.esc_sql($filter['userdata']['value']).'%\'';
4303
+ else $valuecriterion = 'propvalue = \''.esc_sql($filter['userdata']['value']).'\'';
4304
+ $query = 'uploadid in (SELECT DISTINCT uploadid FROM '.$table_name2.' WHERE date_to = 0 AND property = \''.esc_sql($filter['userdata']['field']).'\' AND '.$valuecriterion.')';
4305
+ array_push($queries, $query);
4306
+ }
4307
+
4308
+ /**
4309
+ * Customize Filter Queries.
4310
+ *
4311
+ * This filter allows custom actions to midify the queries that will be used
4312
+ * to filter the selected records of a file viewer.
4313
+ *
4314
+ * @since 4.6.2
4315
+ *
4316
+ * @param array $queries An array of queries to filter the selected records.
4317
+ * @param array $filter The filter array that generated the queries.
4318
+ */
4319
+ $queries = apply_filters("_wfu_filtered_recs_queries", $queries, $filter);
4320
+
4321
+ //Retrieval of uploaded file records is combined with retrieval of userdata
4322
+ //records into one single database query using a left join. This technique,
4323
+ //together with indexing of uploadid fields, results in dramatic speed up of
4324
+ //returned results; all userdata of each uploaded file are encoded into a
4325
+ //single field of the returned results called 'userdata_raw'. The function
4326
+ //then parses userdata_raw and reconstructs the original userdata records.
4327
+ $query = 'SELECT a.*, GROUP_CONCAT(CONCAT_WS("#", b.iduserdata, HEX(b.property), b.propkey, HEX(IFNULL(b.propvalue, "")), b.date_from) ORDER BY b.propkey ASC SEPARATOR "$") AS userdata_raw '.
4328
+ 'FROM '.$table_name1.' a LEFT JOIN '.$table_name2.' b USING (uploadid) '.
4329
+ 'WHERE '.implode(' AND ', $queries).' AND (b.date_to = 0 OR b.date_to IS NULL) GROUP BY a.idlog';
4330
+ $filerecs = $wpdb->get_results($query);
4331
+ $out = array();
4332
+ foreach( $filerecs as $filerec ) {
4333
+ $obsolete = true;
4334
+ //calculate full file path
4335
+ $filepath = wfu_path_rel2abs($filerec->filepath);
4336
+ if ( wfu_file_exists($filepath, "wfu_get_filtered_recs") ) {
4337
+ if ( $plugin_options['hashfiles'] == '1' ) {
4338
+ $filehash = wfu_md5_file($filepath, "wfu_get_filtered_recs");
4339
+ if ( $filehash == $filerec->filehash ) $obsolete = false;
4340
+ }
4341
+ else {
4342
+ $filesize = wfu_filesize($filepath, "wfu_get_filtered_recs");
4343
+ if ( $filesize == $filerec->filesize ) $obsolete = false;
4344
+ }
4345
+ }
4346
+ if ( $obsolete ) {
4347
+ wfu_make_rec_obsolete($filerec);
4348
+ }
4349
+ else {
4350
+ $filerec->userdata = null;
4351
+ if ( $filerec->uploadid != '' ) {
4352
+ $filerec->userdata = array();
4353
+ //the function parses userdata_raw field in order to reconstruct
4354
+ //the original userdata records
4355
+ $items = explode("$", $filerec->userdata_raw);
4356
+ foreach ( $items as $item ) {
4357
+ if ( trim($item) != "" ) {
4358
+ $parts = explode("#", $item);
4359
+ if ( count($parts) == 4 ) {
4360
+ list($id, $label, $key, $value) = $parts;
4361
+ $date_from = '0000-00-00 00:00:00';
4362
+ }
4363
+ else list($id, $label, $key, $value, $date_from) = $parts;
4364
+ $userdata = new stdClass();
4365
+ $userdata->iduserdata = $id;
4366
+ $userdata->uploadid = $filerec->uploadid;
4367
+ $userdata->property = wfu_plugin_decode_string($label);
4368
+ $userdata->propkey = $key;
4369
+ $userdata->propvalue = wfu_plugin_decode_string($value);
4370
+ $userdata->date_from = $date_from;
4371
+ $userdata->date_to = '0000-00-00 00:00:00';
4372
+ array_push($filerec->userdata, $userdata);
4373
+ }
4374
+ }
4375
+ if ( count($filerec->userdata) == 0 ) $filerec->userdata = null;
4376
+ }
4377
+ array_push($out, $filerec);
4378
+ }
4379
+ }
4380
+
4381
+ return $out;
4382
+ }
4383
+
4384
+ /**
4385
+ * Get Uncached Option.
4386
+ *
4387
+ * This function gets an option from the website's Options table. It will first
4388
+ * delete any cached values of the option, so that the stored value in database
4389
+ * is returned.
4390
+ *
4391
+ * @since 3.5.0
4392
+ *
4393
+ * @param string $option The option name to retrieve.
4394
+ * @param mixed $default Optional. A default value to return in case option does
4395
+ * not exist.
4396
+ *
4397
+ * @return mixed The uncached value of the option.
4398
+ */
4399
+ function wfu_get_uncached_option($option, $default = false) {
4400
+ $GLOBALS['wp_object_cache']->delete( $option, 'options' );
4401
+ return get_option($option, $default);
4402
+ }
4403
+
4404
+ /**
4405
+ * Get Plugin Option.
4406
+ *
4407
+ * This function gets a plugin option from the website's Options table. It uses
4408
+ * direct access to options table of the website in order to avoid caching
4409
+ * problems that may happen when retrieving plugin options from parallel server-
4410
+ * side scripts.
4411
+ *
4412
+ * @since 3.5.0
4413
+ *
4414
+ * @global object $wpdb The Wordpress database object.
4415
+ *
4416
+ * @param string $option The option name to retrieve.
4417
+ * @param mixed $default A default value to return in case option does not
4418
+ * exist.
4419
+ * @param string $type Optional. The value type.
4420
+ *
4421
+ * @return mixed The value of the option.
4422
+ */
4423
+ function wfu_get_option($option, $default, $type = "array") {
4424
+ global $wpdb;
4425
+ $table_name1 = $wpdb->prefix . "options";
4426
+ $val = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM $table_name1 WHERE option_name = %s", $option));
4427
+ if ( $val === null && $default !== false ) $val = $default;
4428
+ elseif ( $val !== null ) $val = ( $type == "array" ? wfu_decode_array_from_string($val) : $val );
4429
+ return $val;
4430
+ }
4431
+
4432
+ /**
4433
+ * Get Plugin Option Item.
4434
+ *
4435
+ * This function gets an option item from the website's Options table. Option
4436
+ * items are stored in the option value in an encoded format like this:
4437
+ *
4438
+ * [item_name1]item_value1{item_name1}[item_name2]item_value2{item_name2}...
4439
+ *
4440
+ * This format can be parsed and get the value of a specific item using a single
4441
+ * SQL command. This is exptremely important when working with parallel server-
4442
+ * side scripts, otherwise data may be lost.
4443
+ *
4444
+ * @since 4.12.0
4445
+ *
4446
+ * @global object $wpdb The Wordpress database object.
4447
+ *
4448
+ * @param string $option The option name that contains the item.
4449
+ * @param string $item The item name whose value to retrieve.
4450
+ *
4451
+ * @return null|string Null will be returned if option are item is not found,
4452
+ * otherwise the item value will be returned as string.
4453
+ */
4454
+ function wfu_get_option_item($option, $item) {
4455
+ global $wpdb;
4456
+ $table_name1 = $wpdb->prefix . "options";
4457
+ $val = $wpdb->get_var($wpdb->prepare("SELECT SQL_NO_CACHE IF (COUNT(option_value) = 0, NULL, IF (INSTR(option_value, %s) > 0, SUBSTRING_INDEX(SUBSTRING_INDEX(option_value, %s, -1), %s, 1), NULL)) FROM $table_name1 WHERE option_name = %s", '['.$item.']', '['.$item.']', '{'.$item.'}', $option));
4458
+ //wfu_debug_log("read:".$item." value:".$val."\n");
4459
+ return $val;
4460
+ }
4461
+
4462
+ /**
4463
+ * Check If Plugin Option Item Exists.
4464
+ *
4465
+ * This function checks if an option item in the website's Options table exists.
4466
+ * Option items and their format are described in wfu_get_option_item() function
4467
+ * above.
4468
+ *
4469
+ * @since 4.12.0
4470
+ *
4471
+ * @global object $wpdb The Wordpress database object.
4472
+ *
4473
+ * @param string $option The option name that contains the item.
4474
+ * @param string $item The item name whose existence to check.
4475
+ *
4476
+ * @return null|bool Null will be returned if option is not found, true if the
4477
+ * item exists, false otherwise.
4478
+ */
4479
+ function wfu_option_item_exists($option, $item) {
4480
+ global $wpdb;
4481
+ $table_name1 = $wpdb->prefix . "options";
4482
+ $exists = $wpdb->get_var($wpdb->prepare("SELECT SQL_NO_CACHE IF (COUNT(option_value) = 0, NULL, IF (INSTR(option_value, %s) > 0, TRUE, FALSE)) FROM $table_name1 WHERE option_name = %s", '['.$item.']', $option));
4483
+ return $exists;
4484
+ }
4485
+
4486
+ /**
4487
+ * Update Plugin Option.
4488
+ *
4489
+ * This function updates a plugin array option in the website's Options table or
4490
+ * creates it if it does not exist. It makes direct access to the website's
4491
+ * Options database table. It uses a single SQL command to insert or update the
4492
+ * option. This is necessary when working with parallel server-side scripts,
4493
+ * like the ones created when transferring multiple files to cloud services
4494
+ * asynchronously. The common Wordpress functions get_option() and
4495
+ * update_option() are not sufficient for such operations.
4496
+ *
4497
+ * @since 3.5.0
4498
+ *
4499
+ * @global object $wpdb The Wordpress database object.
4500
+ *
4501
+ * @param string $option The option name to update.
4502
+ * @param mixed $value The new value of the option.
4503
+ * @param string $type Optional. The value type.
4504
+ */
4505
+ function wfu_update_option($option, $value, $type = "array") {
4506
+ global $wpdb;
4507
+ $table_name1 = $wpdb->prefix . "options";
4508
+ $value = ( $type == "array" ? wfu_encode_array_to_string($value) : $value );
4509
+ $wpdb->query($wpdb->prepare("INSERT INTO $table_name1 (option_name, option_value) VALUES (%s, %s) ON DUPLICATE KEY UPDATE option_value = VALUES(option_value)", $option, $value));
4510
+ }
4511
+
4512
+ /**
4513
+ * Run Process in Queue.
4514
+ *
4515
+ * It has been observed that parallel PHP scripts can read/write to the database
4516
+ * and also the file system concurrently. This will cause problems with uploads.
4517
+ * File parts are uploaded concurrently, however it is necessary that each one
4518
+ * is processed at the server-side separately, before the next one starts. The
4519
+ * reason is that when the server reads a new chunk, it stores and retrieves
4520
+ * data from session. If more than one chunks write to session at the same time,
4521
+ * then mixups will happen and the upload will eventually fail.
4522
+ *
4523
+ * This function put processes that need to run concurrently (called 'threads')
4524
+ * in a FIFO queue based on a unique queue ID. The first thread that comes is
4525
+ * the first to be executed. The next one will be executed after the first one
4526
+ * finishes. A timeout loop checks the thread status. If a thread takes too long
4527
+ * to complete, it is considered as failed and it is removed from the queue, so
4528
+ * that the queue continues to the next threads.
4529
+ *
4530
+ * @since 4.12.0
4531
+ *
4532
+ * @param string $queue_id The unique queue ID.
4533
+ * @param string $proc The function that is put in queue.
4534
+ * @param array $params The function parameters.
4535
+ *
4536
+ * @return array {
4537
+ * The result of queue execution.
4538
+ *
4539
+ * @type bool $result True if the process was executed successfully,
4540
+ * false otherwise.
4541
+ * @type string $thread_code The unique code of the current thread.
4542
+ * @type integer $thread_index The index of the current thread.
4543
+ * @type null|mixed $output The return value of the executed function in
4544
+ * case of success, null otherwise.
4545
+ * @type string $error Error code in case of thread execution failure.
4546
+ * }
4547
+ */
4548
+ function wfu_run_process_in_queue($queue_id, $proc, $params) {
4549
+ $ret = array(
4550
+ "result" => false,
4551
+ "thread_code" => "",
4552
+ "thread_index" => 0,
4553
+ "output" => null,
4554
+ "error" => ""
4555
+ );
4556
+ if ( WFU_VAR("WFU_QUEUE_ACTIVE") == "true" ) {
4557
+ $queue = "wfu_queue_".$queue_id;
4558
+ if ( $queue_id == "" ) {
4559
+ $ret["error"] = "noid";
4560
+ return $ret;
4561
+ }
4562
+ $thread_code = wfu_create_random_string(16);
4563
+ wfu_join_queue($queue_id, $thread_code);
4564
+ $limit = intval(WFU_VAR("WFU_QUEUE_THREAD_TIMEOUT"));
4565
+ $waitloop = intval(WFU_VAR("WFU_QUEUE_LOOP_DELAY")) * 1000;
4566
+ $tcheck = time() + $limit;
4567
+ $last_thread = "";
4568
+ $abort = false;
4569
+ while (true) {
4570
+ $cur_thread = wfu_get_queue_thread($queue_id);
4571
+ if ( $cur_thread == $thread_code ) break;
4572
+ //calculate queue activity; if thread has changed then reset timer
4573
+ if ( $cur_thread != $last_thread ) {
4574
+ $last_thread = $cur_thread;
4575
+ $tcheck = time() + $limit;
4576
+ }
4577
+ //if time limit has passed this means that the current queue thread
4578
+ //is not progressing, so we need to exit the queue otherwise there
4579
+ //will be an infinite loop
4580
+ elseif ( time() > $tcheck ) {
4581
+ wfu_remove_queue_thread($queue_id, $thread_code);
4582
+ wfu_remove_queue_thread($queue_id, $cur_thread);
4583
+ $abort = true;
4584
+ break;
4585
+ }
4586
+ usleep($waitloop);
4587
+ }
4588
+ if ( $abort ) {
4589
+ $ret["error"] = "abort_thread";
4590
+ return $ret;
4591
+ }
4592
+ $thread_index = intval(wfu_get_option($queue."_count", 0, "string")) + 1;
4593
+ wfu_update_option($queue."_count", $thread_index, "string");
4594
+ }
4595
+ //create an array of references to the function arguments and pass this to
4596
+ //call_user_func_array instead of $args; this is a workaround to avoid PHP
4597
+ //warnings when the original function passes arguments by reference
4598
+ $args_byref = array();
4599
+ foreach ( $params as $key => &$arg ) $args_byref[$key] = &$arg;
4600
+ $output = call_user_func_array($proc, $args_byref);
4601
+ $ret["result"] = true;
4602
+ $ret["output"] = $output;
4603
+ if ( WFU_VAR("WFU_QUEUE_ACTIVE") == "true" ) {
4604
+ $ret["thread_code"] = $thread_code;
4605
+ $ret["thread_index"] = $thread_index;
4606
+ wfu_advance_queue($queue_id);
4607
+ }
4608
+ return $ret;
4609
+ }
4610
+
4611
+ /**
4612
+ * Join Thread in Queue.
4613
+ *
4614
+ * This function adds a new thread in a queue. If the queue does not exist it
4615
+ * will be created.
4616
+ *
4617
+ * @since 4.12.0
4618
+ *
4619
+ * @param string $queue_id The unique queue ID.
4620
+ * @param string $thread The new thread code.
4621
+ */
4622
+ function wfu_join_queue($queue_id, $thread) {
4623
+ global $wpdb;
4624
+ if ( $queue_id == "" ) return;
4625
+ $queue = "wfu_queue_".$queue_id;
4626
+ $table_name1 = $wpdb->prefix . "options";
4627
+ $wpdb->query($wpdb->prepare("INSERT INTO $table_name1 (option_name, option_value) VALUES (%s, %s) ON DUPLICATE KEY UPDATE option_value = CONCAT(option_value, IF (option_value = '', '', '|'), %s)", $queue, $thread, $thread));
4628
+ }
4629
+
4630
+ /**
4631
+ * Advance Queue.
4632
+ *
4633
+ * This function advances a queue to the next thread.
4634
+ *
4635
+ * @since 4.12.0
4636
+ *
4637
+ * @param string $queue_id The unique queue ID.
4638
+ */
4639
+ function wfu_advance_queue($queue_id) {
4640
+ global $wpdb;
4641
+ if ( $queue_id == "" ) return;
4642
+ $queue = "wfu_queue_".$queue_id;
4643
+ $table_name1 = $wpdb->prefix . "options";
4644
+ $wpdb->query($wpdb->prepare("UPDATE $table_name1 SET option_value = if (instr(option_value, '|') = 0, '', substr(option_value, instr(option_value, '|') + 1)) WHERE option_name = %s", $queue));
4645
+ }
4646
+
4647
+ /**
4648
+ * Get Running Queue Thread.
4649
+ *
4650
+ * This function gets the currently running thread of a queue.
4651
+ *
4652
+ * @since 4.12.0
4653
+ *
4654
+ * @param string $queue_id The unique queue ID.
4655
+ */
4656
+ function wfu_get_queue_thread($queue_id) {
4657
+ global $wpdb;
4658
+ if ( $queue_id == "" ) return;
4659
+ $queue = "wfu_queue_".$queue_id;
4660
+ $table_name1 = $wpdb->prefix . "options";
4661
+ return $wpdb->get_var($wpdb->prepare("SELECT substring_index(option_value, '|', 1) FROM $table_name1 WHERE option_name = %s", $queue));
4662
+ }
4663
+
4664
+ /**
4665
+ * Remove Thread from Queue.
4666
+ *
4667
+ * This function removes a thread from a queue.
4668
+ *
4669
+ * @since 4.12.0
4670
+ *
4671
+ * @param string $queue_id The unique queue ID.
4672
+ * @param string $thread The thread code to remove.
4673
+ */
4674
+ function wfu_remove_queue_thread($queue_id, $thread) {
4675
+ global $wpdb;
4676
+ if ( $queue_id == "" ) return;
4677
+ $queue = "wfu_queue_".$queue_id;
4678
+ $table_name1 = $wpdb->prefix . "options";
4679
+ $wpdb->query($wpdb->prepare("UPDATE $table_name1 SET option_value = replace(replace(replace(replace(option_value, concat('|', %s, '|'), '|'), concat(%s, '|'), ''), concat('|', %s), ''), %s, '') WHERE option_name = %s", $thread, $thread, $thread, $thread, $queue));
4680
+ }
4681
+
4682
+ /**
4683
+ * Remove Queue.
4684
+ *
4685
+ * This function removes a queue from options database table.
4686
+ *
4687
+ * @since 4.12.0
4688
+ *
4689
+ * @param string $queue_id The unique queue ID.
4690
+ */
4691
+ function wfu_remove_queue($queue_id) {
4692
+ if ( $queue_id == "" ) return;
4693
+ $queue = "wfu_queue_".$queue_id;
4694
+ delete_option($queue);
4695
+ }
4696
+
4697
+ /**
4698
+ * Update Plugin Option Item.
4699
+ *
4700
+ * This function updates an option item in the website's Options table. Option
4701
+ * items and their format are described in wfu_get_option_item() function above.
4702
+ * It has to be noted that the update of an option item requires a complex SQL
4703
+ * query, consisting of an INSERT statement calling a SELECT statement. In case
4704
+ * that many such queries are executed at the same time (like it happens when
4705
+ * uploading a file in chunks), database deadlocks may occur. To overcome the
4706
+ * situation, the transaction will be repeated until it succeeds or when a pre-
4707
+ * defined timeout is reached.
4708
+ *
4709
+ * @since 4.12.0
4710
+ *
4711
+ * @global object $wpdb The Wordpress database object.
4712
+ *
4713
+ * @param string $option The option name that contains the item.
4714
+ * @param string $item The item name whose value to retrieve.
4715
+ * @param string $value The new value of the item.
4716
+ *
4717
+ * @return false|int False if there was a DB error, or the number of rows
4718
+ * affected.
4719
+ */
4720
+ function wfu_update_option_item($option, $item, $value) {
4721
+ global $wpdb;
4722
+ $table_name1 = $wpdb->prefix . "options";
4723
+ $timeout = time();
4724
+ $val = false;
4725
+ $suppress_wpdb_errors = $wpdb->suppress_errors;
4726
+ if ( !$suppress_wpdb_errors ) $wpdb->suppress_errors(true);
4727
+ while ( $val === false && time() < $timeout + intval(WFU_VAR("WFU_US_DEADLOCK_TIMEOUT")) ) {
4728
+ $val = $wpdb->query($wpdb->prepare("INSERT INTO $table_name1 (option_name, option_value) SELECT SQL_NO_CACHE %s, IF (COUNT(option_value) = 0, %s, IF (INSTR(option_value, %s) = 0, CONCAT(option_value, %s), CONCAT(SUBSTRING_INDEX(option_value, %s, 1), %s, SUBSTRING_INDEX(option_value, %s, -1)))) FROM $table_name1 WHERE option_name = %s ON DUPLICATE KEY UPDATE option_value = VALUES(option_value)", $option, '['.$item.']'.$value.'{'.$item.'}', '['.$item.']', '['.$item.']'.$value.'{'.$item.'}', '['.$item.']', '['.$item.']'.$value.'{'.$item.'}', '{'.$item.'}', $option));
4729
+ if ( $val === false && WFU_VAR("WFU_US_LOG_DBERRORS") == "true" ) error_log("Database error: ".$wpdb->last_error);
4730
+ }
4731
+ if ( !$suppress_wpdb_errors ) $wpdb->suppress_errors(false);
4732
+ return $val;
4733
+ }
4734
+
4735
+ /**
4736
+ * Delete Plugin Option.
4737
+ *
4738
+ * This function deletes a plugin array option from the website's Options table.
4739
+ * It makes direct access to the website's Options database table so that
4740
+ * caching problems are avoided, when used together with the previous
4741
+ * wfu_get_option() and wfu_update_option() functions.
4742
+ *
4743
+ * @since 4.5.0
4744
+ *
4745
+ * @global object $wpdb The Wordpress database object.
4746
+ *
4747
+ * @param string $option The option name to update.
4748
+ */
4749
+ function wfu_delete_option($option) {
4750
+ global $wpdb;
4751
+ $table_name1 = $wpdb->prefix . "options";
4752
+ $val = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM $table_name1 WHERE option_name = %s", $option));
4753
+ $wpdb->query($wpdb->prepare("DELETE FROM $table_name1 WHERE option_name = %s", $option));
4754
+ }
4755
+
4756
+ /**
4757
+ * Delete Plugin Option Item.
4758
+ *
4759
+ * This function deletes an option item in the website's Options table. Option
4760
+ * items and their format are described in wfu_get_option_item() function above.
4761
+ *
4762
+ * @since 4.12.0
4763
+ *
4764
+ * @global object $wpdb The Wordpress database object.
4765
+ *
4766
+ * @param string $option The option name that contains the item.
4767
+ * @param string $item The item name whose value to retrieve.
4768
+ *
4769
+ * @return false|int False if there was a DB error, or the number of rows
4770
+ * affected.
4771
+ */
4772
+ function wfu_delete_option_item($option, $item) {
4773
+ global $wpdb;
4774
+ $table_name1 = $wpdb->prefix . "options";
4775
+ $timeout = time();
4776
+ $val = false;
4777
+ $suppress_wpdb_errors = $wpdb->suppress_errors;
4778
+ if ( !$suppress_wpdb_errors ) $wpdb->suppress_errors(true);
4779
+ while ( $val === false && time() < $timeout + intval(WFU_VAR("WFU_US_DEADLOCK_TIMEOUT")) ) {
4780
+ $val = $wpdb->query($wpdb->prepare("INSERT INTO $table_name1 (option_name, option_value) SELECT SQL_NO_CACHE %s, IF (COUNT(option_value) = 0, '', IF (INSTR(option_value, %s) = 0, option_value, CONCAT(SUBSTRING_INDEX(option_value, %s, 1), SUBSTRING_INDEX(option_value, %s, -1)))) FROM $table_name1 WHERE option_name = %s ON DUPLICATE KEY UPDATE option_value = VALUES(option_value)", $option, '['.$item.']', '['.$item.']', '{'.$item.'}', $option));
4781
+ if ( $val === false && WFU_VAR("WFU_US_LOG_DBERRORS") == "true" ) error_log("Database error: ".$wpdb->last_error);
4782
+ }
4783
+ if ( !$suppress_wpdb_errors ) $wpdb->suppress_errors(false);
4784
+ return $val;
4785
+ }
4786
+
4787
+ /**
4788
+ * Prepare Data of Uploaded Files for Export.
4789
+ *
4790
+ * This function generates a file that contains data of uploaded files in csv
4791
+ * format for export. It will either export data of all valid uploaded files or
4792
+ * data of all uploaded files (valid or not) of a specififc user.
4793
+ *
4794
+ * @since 3.5.0
4795
+ *
4796
+ * @global object $wpdb The Wordpress database object.
4797
+ *
4798
+ * @redeclarable
4799
+ *
4800
+ * @param array $params An array of parameters to pass to the function.
4801
+ *
4802
+ * @return string The path of the file that contains the prepared data.
4803
+ */
4804
+ function wfu_export_uploaded_files($params) {
4805
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
4806
+ global $wpdb;
4807
+ $table_name1 = $wpdb->prefix . "wfu_log";
4808
+ $table_name2 = $wpdb->prefix . "wfu_userdata";
4809
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
4810
+ $sep = WFU_VAR("WFU_EXPORT_DATA_SEPARATOR");
4811
+ $sep2 = WFU_VAR("WFU_EXPORT_USERDATA_SEPARATOR");
4812
+ $includeall = isset($params["username"]);
4813
+
4814
+ $contents = "";
4815
+ $header = 'Name'.$sep.'Path'.$sep.'Upload User'.$sep.'Upload Time'.$sep.'Size'.$sep.'Page ID'.$sep.'Blog ID'.$sep.'Shortcode ID'.$sep.'Upload ID'.$sep.'User Data';
4816
+ $contents = $header;
4817
+ if ( $includeall ) {
4818
+ $user = get_user_by('login', $params["username"]);
4819
+ $userid = $user->ID;
4820
+ $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE uploaduserid = '.$userid);
4821
+ }
4822
+ else $filerecs = $wpdb->get_results('SELECT * FROM '.$table_name1.' WHERE action <> \'other\' AND date_to = 0');
4823
+ foreach( $filerecs as $filerec ) {
4824
+ if ( $filerec->action == 'datasubmit' ) $obsolete = false;
4825
+ else {
4826
+ $obsolete = true;
4827
+ //calculate full file path
4828
+ $filepath = wfu_path_rel2abs($filerec->filepath);
4829
+ if ( wfu_file_exists($filepath, "wfu_export_uploaded_files") ) {
4830
+ if ( $plugin_options['hashfiles'] == '1' ) {
4831
+ $filehash = wfu_md5_file($filepath, "wfu_export_uploaded_files");
4832
+ if ( $filehash == $filerec->filehash ) $obsolete = false;
4833
+ }
4834
+ else {
4835
+ $filesize = wfu_filesize($filepath, "wfu_export_uploaded_files");
4836
+ if ( $filesize == $filerec->filesize ) $obsolete = false;
4837
+ }
4838
+ }
4839
+ }
4840
+ //export file data if file is not obsolete
4841
+ if ( !$obsolete || $includeall ) {
4842
+ $filepath = wfu_hide_credentials_from_ftpurl($filerec->filepath);
4843
+ $username = wfu_get_username_by_id($filerec->uploaduserid);
4844
+ $filerec->userdata = $wpdb->get_results('SELECT * FROM '.$table_name2.' WHERE uploadid = \''.$filerec->uploadid.'\' AND date_to = 0 ORDER BY propkey');
4845
+ $line = ( $filerec->action == 'datasubmit' ? 'datasubmit' : wfu_basename($filepath) );
4846
+ $line .= $sep.( $filerec->action == 'datasubmit' ? '' : wfu_basedir($filepath) );
4847
+ $line .= $sep.$username;
4848
+ $line .= $sep.( $filerec->uploadtime == null ? "" : date("Y-m-d H:i:s", $filerec->uploadtime) );
4849
+ $line .= $sep.( $filerec->action == 'datasubmit' ? '0' : $filerec->filesize );
4850
+ $line .= $sep.( $filerec->pageid == null ? "" : $filerec->pageid );
4851
+ $line .= $sep.( $filerec->blogid == null ? "" : $filerec->blogid );
4852
+ $line .= $sep.( $filerec->sid == null ? "" : $filerec->sid );
4853
+ $line .= $sep.$filerec->uploadid;
4854
+ $line2 = "";
4855
+ foreach ( $filerec->userdata as $userdata ) {
4856
+ if ( $line2 != "" ) $line2 .= $sep2;
4857
+ $line2 .= $userdata->property.":".str_replace(array("\n", "\r", "\r\n"), " ", $userdata->propvalue);
4858
+ }
4859
+ $line .= $sep.$line2;
4860
+ $contents .= "\n".$line;
4861
+ }
4862
+ }
4863
+ //create file
4864
+ $path = tempnam(sys_get_temp_dir(), 'wfu');
4865
+ file_put_contents($path, $contents);
4866
+
4867
+ return $path;
4868
+ }
4869
+
4870
+ /**
4871
+ * Get All Plugin Options.
4872
+ *
4873
+ * This function gets a list of all plugin's options and variables stored in
4874
+ * user space (usually session).
4875
+ *
4876
+ * @since 4.9.1
4877
+ *
4878
+ * @return array {
4879
+ * An array of all plugin options.
4880
+ *
4881
+ * $type string $name Name of option, an asterisk (*) denotes many
4882
+ * occurencies.
4883
+ * $type string $location Location of option, "db" or "session".
4884
+ * $type bool $deleteOnPurge Delete this option when purging all plugin
4885
+ * data.
4886
+ * $type bool $extract Store this option when extracting plugin data.
4887
+ * }
4888
+ */
4889
+ function wfu_get_all_plugin_options() {
4890
+ //structure of $options array; every item has the following properties:
4891
+ // 0: name of option, an asterisk (*) denotes many occurencies
4892
+ // 1: location of option, "db" or "session"
4893
+ // 2: delete this option when purging all plugin data
4894
+ // 3: store this option when extracting plugin data
4895
+ $options = array(
4896
+ //stored plugin's Settings
4897
+ array( "wordpress_file_upload_options", "db", true, true ),
4898
+ //wfu_log table version
4899
+ array( "wordpress_file_upload_table_log_version", "db", true, true ),
4900
+ //wfu_userdata version
4901
+ array( "wordpress_file_upload_table_userdata_version", "db", true, true ),
4902
+ //wfu_dbxqueue version
4903
+ array( "wordpress_file_upload_table_dbxqueue_version", "db", true, true ),
4904
+ //stored hooks
4905
+ array( "wordpress_file_upload_hooks", "db", true, true ),
4906
+ //transfer manager properties
4907
+ array( "wfu_transfermanager_props", "db", true, true ),
4908
+ //last file record that was read
4909
+ array( "wordpress_file_upload_last_idlog", "db", true, false ),
4910
+ //indices of stored shortcode parameters
4911
+ array( "wfu_params_index", "db", true, false ),
4912
+ //stored shortcode parameters
4913
+ array( "wfu_params_*", "db", true, false ),
4914
+ //stored advanced environment variables
4915
+ array( "wfu_environment_variables", "db", true, true ),
4916
+ //stored global tokens
4917
+ array( "wfu_gst_*", "db", true, false ),
4918
+ //data of unfinished uploaded files
4919
+ array( "wordpress_file_upload_unfinished_data", "db", true, false ),
4920
+ //list of stored variables in dboption user state
4921
+ array( "wfu_userstate_list", "db", true, false ),
4922
+ //stored variable value in dboption user state
4923
+ array( "wfu_userstate_*", "db", true, false ),
4924
+ //last time dboption user state was checked
4925
+ array( "wfu_userstate_list_last_check", "db", true, false ),
4926
+ //stored personal data policies
4927
+ array( "wordpress_file_upload_pd_policies", "db", true, true ),
4928
+ //last time admin was notified about DOS attack
4929
+ array( "wfu_admin_notification_about_DOS", "db", true, false ),
4930
+ //stored token for adding uploader shortcode
4931
+ array( "wfu_add_shortcode_ticket_for_wordpress_file_upload", "session", true, false ),
4932
+ //stored token for adding file viewer shortcode
4933
+ array( "wfu_add_shortcode_ticket_for_wordpress_file_upload_browser", "session", true, false ),
4934
+ //session array holding dir and file paths
4935
+ array( "wfu_filepath_safe_storage", "session", true, false ),
4936
+ //stored rename file flag when renaming file
4937
+ array( "wfu_rename_file", "session", true, false ),
4938
+ //stored rename file error when renaming file
4939
+ array( "wfu_rename_file_error", "session", true, false ),
4940
+ //stored create dir flag when creating dir
4941
+ array( "wfu_create_dir", "session", true, false ),
4942
+ //stored create dir error when creating dir
4943
+ array( "wfu_create_dir_error", "session", true, false ),
4944
+ //stored file details error when updating file details
4945
+ array( "wfu_filedetails_error", "session", true, false ),
4946
+ //stored hook data key when updating a hook
4947
+ array( "wfu_hook_data_key", "session", true, false ),
4948
+ //stored hook data title when updating a hook
4949
+ array( "wfu_hook_data_title", "session", true, false ),
4950
+ //stored hook data description when updating a hook
4951
+ array( "wfu_hook_data_description", "session", true, false ),
4952
+ //stored hook data code when updating a hook
4953
+ array( "wfu_hook_data_code", "session", true, false ),
4954
+ //stored hook data status when updating a hook
4955
+ array( "wfu_hook_data_status", "session", true, false ),
4956
+ //stored hook data scope when updating a hook
4957
+ array( "wfu_hook_data_scope", "session", true, false ),
4958
+ //stored hook data error message when updating a hook
4959
+ array( "wfu_hook_data_message", "session", true, false ),
4960
+ //stored data of file transfers tab
4961
+ array( "wfu_transfers_data", "session", true, false ),
4962
+ //stored token of upload form
4963
+ array( "wfu_token_*", "session", true, false ),
4964
+ //stored data of uploaded files
4965
+ array( "filedata_*", "session", true, false ),
4966
+ //stored status of upload
4967
+ array( "wfu_uploadstatus_*", "session", true, false ),
4968
+ //flag determining if this is the first pass of an upload
4969
+ array( "wfu_upload_first_pass_*", "session", true, false ),
4970
+ //stored approved captcha verification code
4971
+ array( "wfu_approvedcaptcha_*", "session", true, false ),
4972
+ //stored short tokens
4973
+ array( "wfu_ust_*", "session", true, false ),
4974
+ //stored shortcode data
4975
+ array( "wfu_shortcode_data_safe_storage", "session", true, false ),
4976
+ //stored number of deleted thumbnails
4977
+ array( "wfu_deleted_thumbnails_counter", "session", true, false ),
4978
+ //stored number of added thumbnails
4979
+ array( "wfu_added_thumbnails_counter", "session", true, false ),
4980
+ //stored consent data
4981
+ array( "WFU_Consent_Data", "session", true, false ),
4982
+ //stored browser actions
4983
+ array( "wfu_browser_actions_safe_storage", "session", true, false ),
4984
+ //stored data of chunked uploads
4985
+ array( "chunkdata_*", "session", true, false ),
4986
+ //stored flag of uploader form refresh status
4987
+ array( "wfu_check_refresh_*", "session", true, false ),
4988
+ //stored upload start time
4989
+ array( "wfu_start_time_*", "session", true, false ),
4990
+ //stored upload start time
4991
+ array( "wfu_start_time_*", "session", true, false )
4992
+ );
4993
+
4994
+
4995
+ return $options;
4996
+ }
4997
+
4998
+ //********************* Widget Functions ****************************************************************************************
4999
+
5000
+ /**
5001
+ * Get Plugin Widget Object From ID.
5002
+ *
5003
+ * This function gets the object instance of a plugin widget from its ID.
5004
+ *
5005
+ * @since 3.4.0
5006
+ *
5007
+ * @global array $wp_registered_widgets List of all registered widgets.
5008
+ *
5009
+ * @param string $widgetid The ID of the widget object instance.
5010
+ *
5011
+ * @return WP_Widget|false The widget object instance or false if not found.
5012
+ */
5013
+ function wfu_get_widget_obj_from_id($widgetid) {
5014
+ global $wp_registered_widgets;
5015
+
5016
+ if ( !isset($wp_registered_widgets[$widgetid]) ) return false;
5017
+ if ( !isset($wp_registered_widgets[$widgetid]['callback']) ) return false;
5018
+ if ( !isset($wp_registered_widgets[$widgetid]['callback'][0]) ) return false;
5019
+ $obj = $wp_registered_widgets[$widgetid]['callback'][0];
5020
+ if ( !($obj instanceof WP_Widget) ) return false;
5021
+
5022
+ return $obj;
5023
+ }
5024
+
5025
+ //********************* Shortcode Options Functions ****************************************************************************************
5026
+
5027
+ /**
5028
+ * Adjust Shortcode Definitions For Multi-Occurrencies
5029
+ *
5030
+ * This function adjusts shortcode definitions so that more than one attribute
5031
+ * definition exists for components who appear more than one time in placements
5032
+ * attribute (like userdata).
5033
+ *
5034
+ * @since 3.3.0
5035
+ *
5036
+ * @param array $shortcode_atts The shortcode attributes.
5037
+ *
5038
+ * @return array The adjusted shortcode attributes.
5039
+ */
5040
+ function wfu_shortcode_attribute_definitions_adjusted($shortcode_atts) {
5041
+ //get attribute definitions
5042
+ $defs = wfu_attribute_definitions();
5043
+ $defs_indexed = array();
5044
+ $defs_indexed_flat = array();
5045
+ foreach ( $defs as $def ) {
5046
+ $defs_indexed[$def["attribute"]] = $def;
5047
+ $defs_indexed_flat[$def["attribute"]] = $def["value"];
5048
+ }
5049
+ //get placement attribute from shortcode
5050
+ $placements = "";
5051
+ if ( isset($shortcode_atts["placements"]) ) $placements = $shortcode_atts["placements"];
5052
+ else $placements = $defs_indexed_flat["placements"];
5053
+ //get component definitions
5054
+ $components = wfu_component_definitions();
5055
+ //analyse components that can appear more than once in placements
5056
+ foreach ( $components as $component ) {
5057
+ if ( $component["multiplacements"] ) {
5058
+ $componentid = $component["id"];
5059
+ //count component occurrences in placements
5060
+ $component_occurrences = substr_count($placements, $componentid);
5061
+ if ( $component_occurrences > 1 && isset($defs_indexed[$componentid]) ) {
5062
+ //add incremented attribute definitions in $defs_indexed_flat
5063
+ //array if occurrences are more than one
5064
+ for ( $i = 2; $i <= $component_occurrences; $i++ ) {
5065
+ foreach ( $defs_indexed[$componentid]["dependencies"] as $attribute )
5066
+ $defs_indexed_flat[$attribute.$i] = $defs_indexed_flat[$attribute];
5067
+ }
5068
+ }
5069
+ }
5070
+ }
5071
+
5072
+ return $defs_indexed_flat;
5073
+ }
5074
+
5075
+ /**
5076
+ * Generate Shortcode Parameters Index.
5077
+ *
5078
+ * This function generates a unique index number for each shortcode parameters.
5079
+ * The function takes into account the current post ID, the shortcode ID and the
5080
+ * current user's username to construct the index. All identifiers are stored in
5081
+ * 'wfu_params_index' option. The index is used to store the shortcode
5082
+ * attributes in options table for later use.
5083
+ *
5084
+ * @since 2.1.2
5085
+ *
5086
+ * @global object $post The current Post object.
5087
+ *
5088
+ * @param int $shortcode_id The ID of the shortcode.
5089
+ * @param string $user_login The current user's username.
5090
+ *
5091
+ * @return string The index number of the shortcode parameters.
5092
+ */
5093
+ function wfu_generate_current_params_index($shortcode_id, $user_login) {
5094
+ global $post;
5095
+ $cur_index_str = '||'.$post->ID.'||'.$shortcode_id.'||'.$user_login;
5096
+ $cur_index_str_search = '\|\|'.$post->ID.'\|\|'.$shortcode_id.'\|\|'.$user_login;
5097
+ $index_str = get_option('wfu_params_index');
5098
+ $index = explode("&&", $index_str);
5099
+ foreach ($index as $key => $value) if ($value == "") unset($index[$key]);
5100
+ $index_match = preg_grep("/".$cur_index_str_search."$/", $index);
5101
+ if ( count($index_match) == 1 )
5102
+ foreach ( $index_match as $key => $value )
5103
+ if ( $value == "" ) unset($index_match[$key]);
5104
+ if ( count($index_match) <= 0 ) {
5105
+ $cur_index_rand = wfu_create_random_string(16);
5106
+ array_push($index, $cur_index_rand.$cur_index_str);
5107
+ }
5108
+ else {
5109
+ reset($index_match);
5110
+ $cur_index_rand = substr(current($index_match), 0, 16);
5111
+ if ( count($index_match) > 1 ) {
5112
+ $index_match_keys = array_keys($index_match);
5113
+ for ($i = 1; $i < count($index_match); $i++) {
5114
+ $ii = $index_match_keys[$i];
5115
+ unset($index[array_search($index_match[$ii], $index, true)]);
5116
+ }
5117
+ }
5118
+ }
5119
+ if ( count($index_match) != 1 ) {
5120
+ $index_str = implode("&&", $index);
5121
+ update_option('wfu_params_index', $index_str);
5122
+ }
5123
+ return $cur_index_rand;
5124
+ }
5125
+
5126
+ /**
5127
+ * Get Stored Shortcode Parameters.
5128
+ *
5129
+ * This function gets the shortcode parameters, stored in options table, from
5130
+ * its parameters index. Some times the index corresponds to 2 or more sets of
5131
+ * params, so an additional check, based on session token needs to be done in
5132
+ * order to find the correct one.
5133
+ *
5134
+ * @since 2.1.2
5135
+ *
5136
+ * @param string $params_index The parameters index.
5137
+ * @param string $session_token Optional. A session token used to find the
5138
+ * correct params.
5139
+ *
5140
+ * @return array {
5141
+ * The shortcode parameters.
5142
+ *
5143
+ * $type string $unique_id The unique ID of the upload.
5144
+ * $type int $page_id The ID of the page with the upload form.
5145
+ * $type int $shortcode_id The ID of the shortcode.
5146
+ * $type string $user_login The username of the user who made the
5147
+ * upload.
5148
+ * }
5149
+ */
5150
+ function wfu_get_params_fields_from_index($params_index, $session_token = "") {
5151
+ $fields = array();
5152
+ $index_str = get_option('wfu_params_index');
5153
+ $index = explode("&&", $index_str);
5154
+ $index_match = preg_grep("/^".$params_index."/", $index);
5155
+ if ( count($index_match) >= 1 )
5156
+ foreach ( $index_match as $key => $value )
5157
+ if ( $value == "" ) unset($index_match[$key]);
5158
+ if ( count($index_match) > 0 ) {
5159
+ if ( $session_token == "" ) {
5160
+ reset($index_match);
5161
+ list($fields['unique_id'], $fields['page_id'], $fields['shortcode_id'], $fields['user_login']) = explode("||", current($index_match));
5162
+ }
5163
+ //some times $params_index corresponds to 2 or more sets of params, so
5164
+ //we need to check session token in order to find the correct one
5165
+ else {
5166
+ $found = false;
5167
+ foreach ( $index_match as $value ) {
5168
+ list($fields['unique_id'], $fields['page_id'], $fields['shortcode_id'], $fields['user_login']) = explode("||", $value);
5169
+ $sid = $fields['shortcode_id'];
5170
+ if ( WFU_USVAR_exists("wfu_token_".$sid) && WFU_USVAR("wfu_token_".$sid) == $session_token ) {
5171
+ $found = true;
5172
+ break;
5173
+ }
5174
+ }
5175
+ if ( !$found ) $fields = array();
5176
+ }
5177
+ }
5178
+ return $fields;
5179
+ }
5180
+
5181
+ /**
5182
+ * Store Shortcode Data in User's Space.
5183
+ *
5184
+ * This function stores shortcode data in current user's user space (usually
5185
+ * session).
5186
+ *
5187
+ * @since 3.2.0
5188
+ *
5189
+ * @param array $data The shortcode data to store.
5190
+ *
5191
+ * @return string A unique code representing the stored data.
5192
+ */
5193
+ function wfu_safe_store_shortcode_data($data) {
5194
+ $code = wfu_create_random_string(16);
5195
+ $safe_storage = ( WFU_USVAR_exists('wfu_shortcode_data_safe_storage') ? WFU_USVAR('wfu_shortcode_data_safe_storage') : array() );
5196
+ $safe_storage[$code] = $data;
5197
+ WFU_USVAR_store('wfu_shortcode_data_safe_storage', $safe_storage);
5198
+ return $code;
5199
+ }
5200
+
5201
+ /**
5202
+ * Get Stored Shortcode Data from User's Space.
5203
+ *
5204
+ * This function gets stored shortcode data from current user's user space
5205
+ * (usually session).
5206
+ *
5207
+ * @since 3.2.0
5208
+ *
5209
+ * @param string $code A unique code representing the stored data.
5210
+ *
5211
+ * @return array $data The stored shortcode data.
5212
+ */
5213
+ function wfu_get_shortcode_data_from_safe($code) {
5214
+ //sanitize $code
5215
+ $code = wfu_sanitize_code($code);
5216
+ if ( $code == "" ) return '';
5217
+ //return shortcode data from session variable, if exists
5218
+ if ( !WFU_USVAR_exists('wfu_shortcode_data_safe_storage') ) return '';
5219
+ $safe_storage = WFU_USVAR('wfu_shortcode_data_safe_storage');
5220
+ if ( !isset($safe_storage[$code]) ) return '';
5221
+ return $safe_storage[$code];
5222
+ }
5223
+
5224
+ /**
5225
+ * Clear Stored Shortcode Data from User's Space.
5226
+ *
5227
+ * This function clears stored shortcode data from current user's user space
5228
+ * (usually session).
5229
+ *
5230
+ * @since 3.2.0
5231
+ *
5232
+ * @param string $code A unique code representing the stored data.
5233
+ */
5234
+ function wfu_clear_shortcode_data_from_safe($code) {
5235
+ //sanitize $code
5236
+ $code = wfu_sanitize_code($code);
5237
+ if ( $code == "" ) return;
5238
+ //clear shortcode data from session variable, if exists
5239
+ if ( !WFU_USVAR_exists('wfu_shortcode_data_safe_storage') ) return;
5240
+ $safe_storage = WFU_USVAR('wfu_shortcode_data_safe_storage');
5241
+ if ( !isset($safe_storage[$code]) ) return;
5242
+ unset($safe_storage[$code]);
5243
+ WFU_USVAR_store('wfu_shortcode_data_safe_storage', $safe_storage);
5244
+ }
5245
+
5246
+ /**
5247
+ * Decode Dimensions Shortcode Attribute.
5248
+ *
5249
+ * This function converts shortcode attributes keeping dimensions data from
5250
+ * string to array.
5251
+ *
5252
+ * @since 2.1.2
5253
+ *
5254
+ * @param string $dimensions_str The dimensions shortcode attribute.
5255
+ *
5256
+ * @return array An array of element dimension values.
5257
+ */
5258
+ function wfu_decode_dimensions($dimensions_str) {
5259
+ $components = wfu_component_definitions();
5260
+ $dimensions = array();
5261
+
5262
+ foreach ( $components as $comp ) {
5263
+ if ( $comp['dimensions'] == null ) $dimensions[$comp['id']] = "";
5264
+ else foreach ( $comp['dimensions'] as $dimraw ) {
5265
+ list($dim_id, $dim_name) = explode("/", $dimraw);
5266
+ $dimensions[$dim_id] = "";
5267
+ }
5268
+ }
5269
+ $dimensions_raw = explode(",", $dimensions_str);
5270
+ foreach ( $dimensions_raw as $dimension_str ) {
5271
+ $dimension_raw = explode(":", $dimension_str);
5272
+ $item = strtolower(trim($dimension_raw[0]));
5273
+ foreach ( array_keys($dimensions) as $key ) {
5274
+ if ( $item == $key ) $dimensions[$key] = trim($dimension_raw[1]);
5275
+ }
5276
+ }
5277
+ return $dimensions;
5278
+ }
5279
+
5280
+ /**
5281
+ * Remove Item From Placements Attribute.
5282
+ *
5283
+ * This function correctly removes an item from placements attribute of the
5284
+ * uploader shortcode.
5285
+ *
5286
+ * @since 3.8.0
5287
+ *
5288
+ * @param string $placements The placements shortcode attribute.
5289
+ * @param string $item The item to remove.
5290
+ *
5291
+ * @return string The new placements attribute.
5292
+ */
5293
+ function wfu_placements_remove_item($placements, $item) {
5294
+ $itemplaces = explode("/", $placements);
5295
+ $newplacements = array();
5296
+ foreach ( $itemplaces as $section ) {
5297
+ $items_in_section = explode("+", trim($section));
5298
+ $newsection = array();
5299
+ foreach ( $items_in_section as $item_in_section ) {
5300
+ $item_in_section = strtolower(trim($item_in_section));
5301
+ if ( $item_in_section != "" && $item_in_section != $item ) array_push($newsection, $item_in_section);
5302
+ }
5303
+ if ( count($newsection) > 0 ) array_push($newplacements, implode("+", $newsection));
5304
+ }
5305
+ if ( count($newplacements) > 0 ) return implode("/", $newplacements);
5306
+ else return "";
5307
+ }
5308
+
5309
+ //********************* Plugin Design Functions ********************************************************************************************
5310
+
5311
+ /**
5312
+ * Get Uploader Form Template.
5313
+ *
5314
+ * This function gets the template that will be used to render the uploader form
5315
+ * of the plugin. If not template name is defined, the default template will be
5316
+ * used.
5317
+ *
5318
+ * @since 4.0.0
5319
+ *
5320
+ * @redeclarable
5321
+ *
5322
+ * @param string $templatename The template to use.
5323
+ *
5324
+ * @return object The template object to use.
5325
+ */
5326
+ function wfu_get_uploader_template($templatename = "") {
5327
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5328
+ if ($templatename != "") {
5329
+ $classname = "WFU_UploaderTemplate_$templatename";
5330
+ if ( class_exists($classname) )
5331
+ return call_user_func(array($classname, 'get_instance'));
5332
+ $filepath = ABSWPFILEUPLOAD_DIR."templates/uploader-$templatename.php";
5333
+ if ( file_exists($filepath) ) {
5334
+ include_once $filepath;
5335
+ $classname = "WFU_UploaderTemplate_$templatename";
5336
+ if ( class_exists($classname) )
5337
+ return call_user_func(array($classname, 'get_instance'));
5338
+ }
5339
+ }
5340
+ return WFU_Original_Template::get_instance();
5341
+ }
5342
+
5343
+ /**
5344
+ * Get Front-End File Viewer Template.
5345
+ *
5346
+ * This function gets the template that will be used to render the front-end
5347
+ * file viewer of the plugin. If not template name is defined, the default
5348
+ * template will be used.
5349
+ *
5350
+ * @since 4.0.0
5351
+ *
5352
+ * @redeclarable
5353
+ *
5354
+ * @param string $templatename The template to use.
5355
+ *
5356
+ * @return object The template object to use.
5357
+ */
5358
+ function wfu_get_browser_template($templatename = "") {
5359
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5360
+ if ($templatename != "") {
5361
+ $classname = "WFU_BrowserTemplate_$templatename";
5362
+ if ( class_exists($classname) )
5363
+ return call_user_func(array($classname, 'get_instance'));
5364
+ $filepath = ABSWPFILEUPLOAD_DIR."templates/browser-$templatename.php";
5365
+ if ( file_exists($filepath) ) {
5366
+ include_once $filepath;
5367
+ $classname = "WFU_BrowserTemplate_$templatename";
5368
+ if ( class_exists($classname) )
5369
+ return call_user_func(array($classname, 'get_instance'));
5370
+ }
5371
+ }
5372
+ return WFU_Original_Template::get_instance();
5373
+ }
5374
+
5375
+ /**
5376
+ * Add Section in Uploader Form.
5377
+ *
5378
+ * This function adds a section in uploader form with the elements passed in
5379
+ * parameters. The first parameter passed is an array of the shortcode
5380
+ * attributes. The next parameters are the items to add in the new section.
5381
+ *
5382
+ * @since 2.1.2
5383
+ *
5384
+ * @redeclarable
5385
+ *
5386
+ * @return string The HTML code of the new section.
5387
+ */
5388
+ function wfu_add_div() {
5389
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5390
+ $items_count = func_num_args();
5391
+ if ( $items_count == 0 ) return "";
5392
+ $items_raw = func_get_args();
5393
+ $params = $items_raw[0];
5394
+ unset($items_raw[0]);
5395
+ $items = array( );
5396
+ foreach ( $items_raw as $item_raw ) {
5397
+ if ( is_array($item_raw) ) array_push($items, $item_raw);
5398
+ }
5399
+ $items_count = count($items);
5400
+ if ( $items_count == 0 ) return "";
5401
+
5402
+ $template = wfu_get_uploader_template($params["uploadertemplate"]);
5403
+ $data["ID"] = $params["uploadid"];
5404
+ $data["responsive"] = ( $params["fitmode"] == "responsive" );
5405
+ $data["items"] = $items;
5406
+ $data["params"] = $params;
5407
+
5408
+ ob_start();
5409
+ $template->wfu_row_container_template($data);
5410
+ $str_output = ob_get_clean();
5411
+ return $str_output;
5412
+ }
5413
+
5414
+ /**
5415
+ * Generate Plugin Element Template Output.
5416
+ *
5417
+ * This function generates the output of a plugin's element based on the defined
5418
+ * template and the data that the element will have.
5419
+ *
5420
+ * @since 4.0.0
5421
+ *
5422
+ * @param string $blockname The name of the element.
5423
+ * @param array $data An array of data to pass to the element.
5424
+ *
5425
+ * @return array An array holding the output of element. The item 'css' of the
5426
+ * array holds CSS code of the element. The item 'js' holds Javascript
5427
+ * code of the element. Items 'line1', 'line2' and so on hold the lines
5428
+ * of the HTML code of the element.
5429
+ */
5430
+ function wfu_read_template_output($blockname, $data) {
5431
+ $output = array();
5432
+ if ( isset($data["params"]["uploadertemplate"]) ) $template = wfu_get_uploader_template($data["params"]["uploadertemplate"]);
5433
+ else $template = wfu_get_browser_template($data["params"]["browsertemplate"]);
5434
+ $func = "wfu_".$blockname."_template";
5435
+ $sid = $data["ID"];
5436
+ ob_start();
5437
+ call_user_func(array($template, $func), $data);
5438
+ $str_output = ob_get_clean();
5439
+
5440
+ $str_output = str_replace('$ID', $sid, $str_output);
5441
+ //extract css, javascript and HTML from output
5442
+ $match = array();
5443
+ preg_match("/<style>(.*)<\/style>.*?<script.*?>(.*)<\/script>(.*)/s", $str_output, $match);
5444
+ if ( count($match) == 4 ) {
5445
+ $output["css"] = trim($match[1]);
5446
+ $output["js"] = trim($match[2]);
5447
+ $html = trim($match[3]);
5448
+ $i = 1;
5449
+ foreach( preg_split("/((\r?\n)|(\r\n?))/", $html) as $line )
5450
+ $output["line".$i++] = $line;
5451
+ }
5452
+
5453
+ return $output;
5454
+ }
5455
+
5456
+ /**
5457
+ * Generate Plugin Element Output.
5458
+ *
5459
+ * This function generates the final HTML code of a plugin's element that is
5460
+ * ready for output.
5461
+ *
5462
+ * @since 4.0.0
5463
+ *
5464
+ * @param string $blockname The name of the element.
5465
+ * @param array $params The shortcode attributes.
5466
+ * @param array $additional_params Additional parameters passed to the function
5467
+ * specific to the element.
5468
+ * @param int $occurrence_index The occurrence index of the element, in case
5469
+ * that placements attribute contains more than one occurrencies of this
5470
+ * element.
5471
+ *
5472
+ * @return string The HTML code of the element.
5473
+ */
5474
+ function wfu_template_to_HTML($blockname, $params, $additional_params, $occurrence_index) {
5475
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
5476
+ $block = call_user_func("wfu_prepare_".$blockname."_block", $params, $additional_params, $occurrence_index);
5477
+ if ( isset($params["uploadid"]) ) {
5478
+ $ID = $params["uploadid"];
5479
+ $WF = "WFU";
5480
+ }
5481
+ else {
5482
+ $ID = $params["browserid"];
5483
+ $WF = "WFUB";
5484
+ }
5485
+ $css = $block["css"];
5486
+ if ( $block["js"] != "" ) {
5487
+ $js = 'var '.$WF.'_JS_'.$ID.'_'.$blockname.' = function() {';
5488
+ $js .= "\n".$block["js"];
5489
+ $js .= "\n".'}';
5490
+ $js .= "\n".'wfu_run_js("window", "'.$WF.'_JS_'.$ID.'_'.$blockname.'");';
5491
+ }
5492
+ //relax css rules if this option is enabled
5493
+ if ( $plugin_options['relaxcss'] == '1' ) $css = preg_replace('#.*?/\*relax\*/\s*#', '', $css);
5494
+ $echo_str = wfu_css_to_HTML($css);
5495
+ $echo_str .= "\n".wfu_js_to_HTML($js);
5496
+ $k = 1;
5497
+ while ( isset($block["line".$k]) ) {
5498
+ if ( $block["line".$k] != "" ) $echo_str .= "\n".$block["line".$k];
5499
+ $k++;
5500
+ }
5501
+
5502
+ return $echo_str;
5503
+ }
5504
+
5505
+ /**
5506
+ * Extract CSS and Javascript Code From Components.
5507
+ *
5508
+ * This function extracts CSS and Javascript code from a components array
5509
+ * holding its output.
5510
+ *
5511
+ * @since 4.0.0
5512
+ *
5513
+ * @param array $section_array The component output to analyse.
5514
+ * @param string $css The parameter to store extracted CSS code.
5515
+ * @param string $js The parameter to store extracted Javascript code.
5516
+ */
5517
+ function wfu_extract_css_js_from_components($section_array, &$css, &$js) {
5518
+ for ( $i = 1; $i < count($section_array); $i++ ) {
5519
+ if ( isset($section_array[$i]["css"]) ) $css .= ( $css == "" ? "" : "\n" ).$section_array[$i]["css"];
5520
+ if ( isset($section_array[$i]["js"]) ) $js .= ( $js == "" ? "" : "\n" ).$section_array[$i]["js"];
5521
+ }
5522
+ return;
5523
+ }
5524
+
5525
+ /**
5526
+ * Add Loading Overlay in Plugin's Form.
5527
+ *
5528
+ * This function adds an overlay onto a plugin's form (uploader form or file
5529
+ * viewer) that shows a 'loading' icon when necessary.
5530
+ *
5531
+ * @since 3.5.0
5532
+ *
5533
+ * @redeclarable
5534
+ *
5535
+ * @param string $dlp Tab prefix of each HTML line.
5536
+ * @param string $code A code string to uniquely identify the overlay.
5537
+ *
5538
+ * @return string The HTML code of the loading overlay.
5539
+ */
5540
+ function wfu_add_loading_overlay($dlp, $code) {
5541
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5542
+ $echo_str = $dlp.'<div id="wfu_'.$code.'_overlay" style="margin:0; padding: 0; width:100%; height:100%; position:absolute; left:0; top:0; border:none; background:none; display:none;">';
5543
+ $echo_str .= $dlp."\t".'<div style="margin:0; padding: 0; width:100%; height:100%; position:absolute; left:0; top:0; border:none; background-color:rgba(255,255,255,0.8); z-index:1;""></div>';
5544
+ $echo_str .= $dlp."\t".'<table style="margin:0; padding: 0; table-layout:fixed; width:100%; height:100%; position:absolute; left:0; top:0; border:none; background:none; z-index:2;"><tbody><tr><td align="center" style="border:none;">';
5545
+ $echo_str .= $dlp."\t\t".'<img src="'.WFU_IMAGE_OVERLAY_LOADING.'" /><br /><span>loading...</span>';
5546
+ $echo_str .= $dlp."\t".'</td></tr></tbody></table>';
5547
+ $echo_str .= $dlp.'</div>';
5548
+
5549
+ return $echo_str;
5550
+ }
5551
+
5552
+ /**
5553
+ * Add Pagination Header in Plugin's Form.
5554
+ *
5555
+ * This function adds a pagination header onto a plugin's form (uploader form or
5556
+ * file viewer).
5557
+ *
5558
+ * @since 3.5.0
5559
+ *
5560
+ * @redeclarable
5561
+ *
5562
+ * @param string $dlp Tab prefix of each HTML line.
5563
+ * @param string $code A code string to uniquely identify the pagination header.
5564
+ * @param int $curpage The current page to show in the pagination header.
5565
+ * @param int $pages Number of pages of the pagination header.
5566
+ * @param bool $nonce Optional. If false then a nonce will also be created.
5567
+ *
5568
+ * @return string The HTML code of the pagination header.
5569
+ */
5570
+ function wfu_add_pagination_header($dlp, $code, $curpage, $pages, $nonce = false) {
5571
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5572
+ if ($nonce === false) $nonce = wp_create_nonce( 'wfu-'.$code.'-page' );
5573
+ $echo_str = $dlp.'<div style="float:right;">';
5574
+ $echo_str .= $dlp."\t".'<label id="wfu_'.$code.'_first_disabled" style="margin:0 4px; font-weight:bold; opacity:0.5; cursor:default; display:'.( $curpage == 1 ? 'inline' : 'none' ).';">&#60;&#60;</label>';
5575
+ $echo_str .= $dlp."\t".'<label id="wfu_'.$code.'_prev_disabled" style="margin:0 4px; font-weight:bold; opacity:0.5; cursor:default; display:'.( $curpage == 1 ? 'inline' : 'none' ).';">&#60;</label>';
5576
+ $echo_str .= $dlp."\t".'<a id="wfu_'.$code.'_first" href="javascript:wfu_goto_'.$code.'_page(\''.$nonce.'\', \'first\');" style="margin:0 4px; font-weight:bold; display:'.( $curpage == 1 ? 'none' : 'inline' ).';">&#60;&#60;</a>';
5577
+ $echo_str .= $dlp."\t".'<a id="wfu_'.$code.'_prev" href="javascript:wfu_goto_'.$code.'_page(\''.$nonce.'\', \'prev\');" style="margin:0 4px; font-weight:bold; display:'.( $curpage == 1 ? 'none' : 'inline' ).';">&#60;</a>';
5578
+ $echo_str .= $dlp."\t".'<label style="margin:0 0 0 4px; cursor:default;">'.WFU_PAGINATION_PAGE.'</label>';
5579
+ $echo_str .= $dlp."\t".'<select id="wfu_'.$code.'_pages" style="margin:0 4px;" onchange="wfu_goto_'.$code.'_page(\''.$nonce.'\', \'sel\');">';
5580
+ for ( $i = 1; $i <= $pages; $i++ )
5581
+ $echo_str .= $dlp."\t\t".'<option value="'.$i.'"'.( $i == $curpage ? ' selected="selected"' : '' ).'>'.$i.'</option>';
5582
+ $echo_str .= $dlp."\t".'</select>';
5583
+ $echo_str .= $dlp."\t".'<label style="margin:0 4px 0 0; cursor:default;">'.WFU_PAGINATION_OF.$pages.'</label>';
5584
+ $echo_str .= $dlp."\t".'<label id="wfu_'.$code.'_next_disabled" style="margin:0 4px; font-weight:bold; opacity:0.5; cursor:default; display:'.( $curpage == $pages ? 'inline' : 'none' ).';">&#62;</label>';
5585
+ $echo_str .= $dlp."\t".'<label id="wfu_'.$code.'_last_disabled" style="margin:0 4px; font-weight:bold; opacity:0.5; cursor:default; display:'.( $curpage == $pages ? 'inline' : 'none' ).';">&#62;&#62;</label>';
5586
+ $echo_str .= $dlp."\t".'<a id="wfu_'.$code.'_next" href="javascript:wfu_goto_'.$code.'_page(\''.$nonce.'\', \'next\');" style="margin:0 4px; font-weight:bold; display:'.( $curpage == $pages ? 'none' : 'inline' ).';">&#62;</a>';
5587
+ $echo_str .= $dlp."\t".'<a id="wfu_'.$code.'_last" href="javascript:wfu_goto_'.$code.'_page(\''.$nonce.'\', \'last\');" style="margin:0 4px; font-weight:bold; display:'.( $curpage == $pages ? 'none' : 'inline' ).';">&#62;&#62;</a>';
5588
+ $echo_str .= $dlp.'</div>';
5589
+
5590
+ return $echo_str;
5591
+ }
5592
+
5593
+ /**
5594
+ * Add Bulk Actions Header in Plugin's Form.
5595
+ *
5596
+ * This function adds a bulk actions header onto a plugin's form (file viewer).
5597
+ *
5598
+ * @since 3.8.5
5599
+ *
5600
+ * @redeclarable
5601
+ *
5602
+ * @param string $dlp Tab prefix of each HTML line.
5603
+ * @param string $code A code string to uniquely identify the bulk actions
5604
+ * header.
5605
+ * @param array $actions {
5606
+ * The list of actions of the bulk actions header.
5607
+ *
5608
+ * $type string $name The name slug of the action.
5609
+ * $type string $title The title of the action.
5610
+ * }
5611
+ *
5612
+ * @return string The HTML code of the bulk actions header.
5613
+ */
5614
+ function wfu_add_bulkactions_header($dlp, $code, $actions) {
5615
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5616
+ $echo_str = $dlp.'<div style="float:left;">';
5617
+ $echo_str .= $dlp."\t".'<select id="wfu_'.$code.'_bulkactions" onchange="wfu_apply_bulkaction_select(\''.$code.'\');">';
5618
+ $echo_str .= $dlp."\t\t".'<option value="" selected="selected">'.( substr($code, 0, 8) == "browser_" ? WFU_BROWSER_BULKACTION_TITLE : "Bulk Actions").'</option>';
5619
+ foreach ( $actions as $action )
5620
+ $echo_str .= $dlp."\t\t".'<option value="'.$action["name"].'">'.$action["title"].'</option>';
5621
+ $echo_str .= $dlp."\t".'</select>';
5622
+ $echo_str .= $dlp."\t".'<input type="button" class="button action" value="'.( substr($code, 0, 8) == "browser_" ? WFU_BROWSER_BULKACTION_LABEL : "Apply").'" onclick="wfu_apply_'.$code.'_bulkaction();" />';
5623
+ $echo_str .= $dlp."\t".'<img src="'.WFU_IMAGE_OVERLAY_LOADING.'" style="display:none;" />';
5624
+ $echo_str .= $dlp.'</div>';
5625
+
5626
+ return $echo_str;
5627
+ }
5628
+
5629
+ /**
5630
+ * Add Filter Header in Plugin's Form.
5631
+ *
5632
+ * This function adds a multi-select filter header onto a plugin's forms.
5633
+ *
5634
+ * @since 4.16.0
5635
+ *
5636
+ * @redeclarable
5637
+ *
5638
+ * @param string $dlp Tab prefix of each HTML line.
5639
+ * @param string $code A code string to uniquely identify the filter header.
5640
+ * @param array $filters {
5641
+ * The list of filters.
5642
+ *
5643
+ * $type string $code The unique filter code.
5644
+ * $type string $title The title of the filter.
5645
+ * $type int $count The number of items matching the filter.
5646
+ * $type bool $checked Whether this filter is checked.
5647
+ * }
5648
+ *
5649
+ * @return string The HTML code of the filter header.
5650
+ */
5651
+ function wfu_add_multifilter_header($dlp, $code, $filters, $is_first) {
5652
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5653
+ $echo_str = $dlp.'<div class="wfu-filters"'.( $is_first ? '' : ' style="margin-left: 1em;"' ).'>';
5654
+ $echo_str .= $dlp."\t".'<ul class="subsubsub">';
5655
+ $i = 0;
5656
+ foreach ( $filters as $filter ) {
5657
+ $echo_str .= $dlp."\t\t".'<li class="'.$filter["code"].'">';
5658
+ $echo_str .= $dlp."\t\t\t".'<input id="filter-'.$i.'" type="checkbox"'.( $filter["checked"] ? ' checked="checked"' : '' ).' onchange="wfu_filter_check_changed(this);" />';
5659
+ $echo_str .= $dlp."\t\t\t".'<label for="filter-'.$i.'"'.( $filter["checked"] ? ' class="current" aria-current="page"' : '' ).'>'.$filter["title"].' ';
5660
+ $echo_str .= $dlp."\t\t\t\t".'<span class="count">('.$filter["count"].')</span>';
5661
+ $echo_str .= $dlp."\t\t\t".'</label>';
5662
+ if ( $i < count($filters) - 1 ) $echo_str .= ' |';
5663
+ $echo_str .= $dlp."\t\t".'</li>';
5664
+ $i++;
5665
+ }
5666
+ $echo_str .= $dlp."\t".'</ul>';
5667
+ $echo_str .= $dlp."\t".'<input type="button" class="button action" value="Apply" onclick="wfu_apply_'.$code.'_filter();" />';
5668
+ $echo_str .= $dlp.'</div>';
5669
+
5670
+ return $echo_str;
5671
+ }
5672
+
5673
+ /**
5674
+ * Parse Colors From Color Template.
5675
+ *
5676
+ * This function converts a color template (color triplet) into an array of
5677
+ * color values.
5678
+ *
5679
+ * @since 2.1.2
5680
+ *
5681
+ * @param string $template A color template to parse.
5682
+ *
5683
+ * @return array {
5684
+ * A triplet of color values.
5685
+ *
5686
+ * $type string $color Text color value.
5687
+ * $type string $bgcolor Background color value.
5688
+ * $type string $borcolor Border color value.
5689
+ * }
5690
+ */
5691
+ function wfu_prepare_message_colors($template) {
5692
+ $color_array = explode(",", $template);
5693
+ $colors['color'] = $color_array[0];
5694
+ $colors['bgcolor'] = $color_array[1];
5695
+ $colors['borcolor'] = $color_array[2];
5696
+ return $colors;
5697
+ }
5698
+
5699
+ //********************* Email Functions ****************************************************************************************************
5700
+
5701
+ /**
5702
+ * Send Notification Email.
5703
+ *
5704
+ * This function sends a notification email after files have been uploaded.
5705
+ *
5706
+ * @since 2.1.2
5707
+ *
5708
+ * @global object $blog_id The ID of the current blog.
5709
+ *
5710
+ * @redeclarable
5711
+ *
5712
+ * @param object $user The user that uploaded the files.
5713
+ * @param array $uploaded_file_paths An array of full paths of the uploaded
5714
+ * files.
5715
+ * @param array $userdata_fields An array of userdata fields, if any.
5716
+ * @param array $params The shortcode attributes.
5717
+ *
5718
+ * @return string Empty if operation was successful, an error message otherwise.
5719
+ */
5720
+ function wfu_send_notification_email($user, $uploaded_file_paths, $userdata_fields, $params) {
5721
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5722
+ global $blog_id;
5723
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
5724
+
5725
+ //get consent status
5726
+ $consent_revoked = ( $plugin_options["personaldata"] == "1" && $params["consent_result"] == "0" );
5727
+ $not_store_files = ( $params["personaldatatypes"] == "userdata and files" );
5728
+ //create necessary variables
5729
+ $only_filename_list = "";
5730
+ $target_path_list = "";
5731
+ foreach ( $uploaded_file_paths as $filepath ) {
5732
+ $only_filename_list .= ( $only_filename_list == "" ? "" : ", " ).wfu_basename($filepath);
5733
+ $target_path_list .= ( $target_path_list == "" ? "" : ", " ).$filepath;
5734
+ }
5735
+
5736
+ //apply wfu_before_email_notification filter
5737
+ $changable_data['recipients'] = $params["notifyrecipients"];
5738
+ $changable_data['subject'] = $params["notifysubject"];
5739
+ $changable_data['message'] = $params["notifymessage"];
5740
+ $changable_data['headers'] = $params["notifyheaders"];
5741
+ $changable_data['user_data'] = $userdata_fields;
5742
+ $changable_data['filename'] = $only_filename_list;
5743
+ $changable_data['filepath'] = $target_path_list;
5744
+ $changable_data['error_message'] = '';
5745
+ $additional_data['shortcode_id'] = $params["uploadid"];
5746
+ /**
5747
+ * Customize Notification Email.
5748
+ *
5749
+ * This filter allows custom actions to modify the notification email
5750
+ * that is sent after a file upload.
5751
+ *
5752
+ * @since 2.7.3
5753
+ *
5754
+ * @param array $changable_data {
5755
+ * Email parameters that can be changed.
5756
+ *
5757
+ * @type string $recipients A comma-separated list of email recipients.
5758
+ * @type string $subject The email subject.
5759
+ * @type string $message The email body.
5760
+ * @type array $user_data Additional user data associated with the
5761
+ * uploaded files.
5762
+ * @type string $filename A comma-separated list of file names.
5763
+ * @type string $filepath A comma-separated list of file full paths.
5764
+ * @type string $error_message An error message that needs to be
5765
+ * populated in case the email must not be sent.
5766
+ * }
5767
+ * @param array $additional_data {
5768
+ * Additional parameters of the upload.
5769
+ *
5770
+ * @type int $shortcode_id The plugin ID of the upload form.
5771
+ * }
5772
+ */
5773
+ $ret_data = apply_filters('wfu_before_email_notification', $changable_data, $additional_data);
5774
+
5775
+ if ( $ret_data['error_message'] == '' ) {
5776
+ $notifyrecipients = $ret_data['recipients'];
5777
+ $notifysubject = $ret_data['subject'];
5778
+ $notifymessage = $ret_data['message'];
5779
+ $notifyheaders = $ret_data['headers'];
5780
+ $userdata_fields = $ret_data['user_data'];
5781
+ $only_filename_list = $ret_data['filename'];
5782
+ $target_path_list = $ret_data['filepath'];
5783
+
5784
+ if ( 0 == $user->ID ) {
5785
+ $user_login = "guest";
5786
+ $user_email = "";
5787
+ }
5788
+ else {
5789
+ $user_login = $user->user_login;
5790
+ $user_email = $user->user_email;
5791
+ }
5792
+ $search = array ('/%useremail%/', '/%n%/', '/%dq%/', '/%brl%/', '/%brr%/');
5793
+ $replace = array ($user_email, "\n", "\"", "[", "]");
5794
+ foreach ( $userdata_fields as $userdata_key => $userdata_field ) {
5795
+ $ind = 1 + $userdata_key;
5796
+ array_push($search, '/%userdata'.$ind.'%/');
5797
+ array_push($replace, $userdata_field["value"]);
5798
+ }
5799
+ // $notifyrecipients = trim(preg_replace('/%useremail%/', $user_email, $params["notifyrecipients"]));
5800
+ $notifyrecipients = preg_replace($search, $replace, $notifyrecipients);
5801
+ $search = array ('/%n%/', '/%dq%/', '/%brl%/', '/%brr%/');
5802
+ $replace = array ("\n", "\"", "[", "]");
5803
+ $notifyheaders = preg_replace($search, $replace, $notifyheaders);
5804
+ $search = array ('/%username%/', '/%useremail%/', '/%filename%/', '/%filepath%/', '/%blogid%/', '/%pageid%/', '/%pagetitle%/', '/%n%/', '/%dq%/', '/%brl%/', '/%brr%/');
5805
+ $replace = array ($user_login, ( $user_email == "" ? "no email" : $user_email ), $only_filename_list, $target_path_list, $blog_id, $params["pageid"], get_the_title($params["pageid"]), "\n", "\"", "[", "]");
5806
+ foreach ( $userdata_fields as $userdata_key => $userdata_field ) {
5807
+ $ind = 1 + $userdata_key;
5808
+ array_push($search, '/%userdata'.$ind.'%/');
5809
+ array_push($replace, $userdata_field["value"]);
5810
+ }
5811
+ $notifysubject = preg_replace($search, $replace, $notifysubject);
5812
+ $notifymessage = preg_replace($search, $replace, $notifymessage);
5813
+
5814
+ if ( $params["attachfile"] == "true" ) {
5815
+ $notify_sent = wp_mail($notifyrecipients, $notifysubject, $notifymessage, $notifyheaders, $uploaded_file_paths);
5816
+ }
5817
+ else {
5818
+ $notify_sent = wp_mail($notifyrecipients, $notifysubject, $notifymessage, $notifyheaders);
5819
+ }
5820
+ //delete files if it is required by consent policy
5821
+ if ( $consent_revoked && $not_store_files ) {
5822
+ foreach ( $uploaded_file_paths as $file ) wfu_unlink($file, "wfu_send_notification_email");
5823
+ }
5824
+ return ( $notify_sent ? "" : WFU_WARNING_NOTIFY_NOTSENT_UNKNOWNERROR );
5825
+ }
5826
+ else return $ret_data['error_message'];
5827
+ }
5828
+
5829
+ /**
5830
+ * Send Notification Email to Admin.
5831
+ *
5832
+ * This function sends a notification email to admin.
5833
+ *
5834
+ * @since 3.9.0
5835
+ *
5836
+ * @redeclarable
5837
+ *
5838
+ * @param string $subject The email subject.
5839
+ * @param string $message The emal message.
5840
+ */
5841
+ function wfu_notify_admin($subject, $message) {
5842
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5843
+ $admin_email = get_option("admin_email");
5844
+ if ( $admin_email === false ) return;
5845
+ wp_mail($admin_email, $subject, $message);
5846
+ }
5847
+
5848
+ //********************* Media Functions ****************************************************************************************************
5849
+
5850
+ /**
5851
+ * Create Media Attachment of Uploaded File.
5852
+ *
5853
+ * This function creates a media attachment and associates it with an uploaded
5854
+ * file.
5855
+ *
5856
+ * This function incorporates contributions from Aaron Olin who made some
5857
+ * corrections regarding the upload path.
5858
+ *
5859
+ * @since 2.2.1
5860
+ *
5861
+ * @redeclarable
5862
+ *
5863
+ * @param string $file_path The file path of the uploaded file.
5864
+ * @param array $userdata_fields Any userdata fields defined with the file.
5865
+ * @param int $page_id The ID of a page to link the attachment.
5866
+ *
5867
+ * @return int The ID of the created Media attachment.
5868
+ */
5869
+ function wfu_process_media_insert($file_path, $userdata_fields, $page_id){
5870
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5871
+ $wp_upload_dir = wp_upload_dir();
5872
+ $filetype = wp_check_filetype( wfu_basename( $file_path ), null );
5873
+
5874
+ $attachment = array(
5875
+ 'guid' => $wp_upload_dir['url'] . '/' . wfu_basename( $file_path ),
5876
+ 'post_mime_type' => $filetype['type'],
5877
+ 'post_title' => preg_replace( '/\.[^.]+$/', '', wfu_basename( $file_path ) ),
5878
+ 'post_content' => '',
5879
+ 'post_status' => 'inherit'
5880
+ );
5881
+
5882
+ $attach_id = wp_insert_attachment( $attachment, $file_path, $page_id );
5883
+
5884
+ // If file is an image, process the default thumbnails for previews
5885
+ require_once(ABSPATH . 'wp-admin/includes/image.php');
5886
+ $attach_data = wp_generate_attachment_metadata( $attach_id, $file_path );
5887
+ // Add userdata as attachment metadata
5888
+ foreach ( $userdata_fields as $userdata_field )
5889
+ $attach_data["WFU User Data"][$userdata_field["label"]] = $userdata_field["value"];
5890
+ $update_attach = wp_update_attachment_metadata( $attach_id, $attach_data );
5891
+ // link attachment with file in plugin's database
5892
+ $filedata = wfu_get_filedata($file_path, true);
5893
+ if ( $filedata != null ) {
5894
+ $filedata["media"] = array(
5895
+ "type" => "data",
5896
+ "attach_id" => $attach_id
5897
+ );
5898
+ wfu_save_filedata_from_id($filedata["general"]["idlog"], $filedata);
5899
+ }
5900
+
5901
+ return $attach_id;
5902
+ }
5903
+
5904
+ /**
5905
+ * Check If File Extension is Common Image.
5906
+ *
5907
+ * This function checks whether a file extension is a common image.
5908
+ *
5909
+ * @since 4.13.1
5910
+ *
5911
+ * @redeclarable
5912
+ *
5913
+ * @param string $ext The file extension to check.
5914
+ *
5915
+ * @return bool True if the extension is image, false otherwise.
5916
+ */
5917
+ function wfu_file_extension_is_common_image($ext) {
5918
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
5919
+ //define valid image types
5920
+ $images = array( "jpeg", "jpg", "jpe", "pjpeg", "gif", "png", "tif", "bmp" );
5921
+ return in_array($ext, $images);
5922
+ }
5923
+
5924
+ //********************* Form Fields Functions ****************************************************************************************************
5925
+
5926
+ /**
5927
+ * Parse Userdata Callback.
5928
+ *
5929
+ * This is a callback function used in userdata parsing.
5930
+ *
5931
+ * @since 3.3.1
5932
+ *
5933
+ * @param string $matches A preg_replace_callback() function match.
5934
+ *
5935
+ * @return string The processed $matches string.
5936
+ */
5937
+ function wfu_preg_replace_callback_func($matches) {
5938
+ return str_replace("[/]", "/", $matches[0]);
5939
+ }
5940
+
5941
+ /**
5942
+ * Parse Upload Form Userdata.
5943
+ *
5944
+ * This function parses userdatalabel attribute, which holds userdata fields
5945
+ * properties, into an array.
5946
+ *
5947
+ * @since 3.3.0
5948
+ *
5949
+ * @param string $value Upload form userdatalabel attribute.
5950
+ *
5951
+ * @return array {
5952
+ * Parsed userdata fields properties.
5953
+ *
5954
+ * $type array {
5955
+ * Parsed userdata field properties.
5956
+ *
5957
+ * $type string $type The type of the field.
5958
+ * $type string $label The label of the field.
5959
+ * $type string $labelposition The position of the label in
5960
+ * relation to the field.
5961
+ * $type bool $required Field is required.
5962
+ * $type bool $donotautocomplete Field must not be autocompleted.
5963
+ * $type bool $validate Validate the field before upload.
5964
+ * $type bool $typehook Apply a hook on the field while typing.
5965
+ * $type string $hintposition The position of the hint text in
5966
+ * relation to the field.
5967
+ * $type string $default The default value of the field.
5968
+ * $type string $data A data property specific per field type.
5969
+ * $type string $group The field is grouped with other fields.
5970
+ * $type string $format Field format, specific per type.
5971
+ * }
5972
+ * }
5973
+ */
5974
+ function wfu_parse_userdata_attribute($value){
5975
+ $fields = array();
5976
+ //read defaults
5977
+ $definitions_unindexed = wfu_formfield_definitions();
5978
+ $defaults = array();
5979
+ foreach ( $definitions_unindexed as $def ) {
5980
+ $default = array();
5981
+ $default["type"] = $def["type"];
5982
+ $default["label"] = $def["label"];
5983
+ $default["labelposition"] = "".substr($def["labelposition"], 5);
5984
+ $default["required"] = ( substr($def["required"], 5) == "true" );
5985
+ $default["donotautocomplete"] = ( substr($def["donotautocomplete"], 5) == "true" );
5986
+ $default["validate"] = ( substr($def["validate"], 5) == "true" );
5987
+ $default["typehook"] = ( substr($def["typehook"], 5) == "true" );
5988
+ $default["hintposition"] = "".substr($def["hintposition"], 5);
5989
+ $default["default"] = "".substr($def["default"], 5);
5990
+ $default["data"] = "".substr($def["data"], 5);
5991
+ $default["group"] = "".substr($def["group"], 5);
5992
+ $default["format"] = "".substr($def["format"], 5);
5993
+ $defaults[$def["type"]] = $default;
5994
+ }
5995
+ // $fields_arr = explode("/", $value);
5996
+ $value = str_replace("/", "[/]", $value);
5997
+ $value = preg_replace_callback("/\(.*\)/", "wfu_preg_replace_callback_func", $value);
5998
+ $fields_arr = explode("[/]", $value);
5999
+ //parse shortcode attribute to $fields
6000
+ foreach ( $fields_arr as $field_raw ) {
6001
+ $field_raw = trim($field_raw);
6002
+ $fieldprops = $defaults["text"];
6003
+ //read old default attribute
6004
+ if ( substr($field_raw, 0, 1) == "*" ) {
6005
+ $fieldprops["required"] = true;
6006
+ $field_raw = substr($field_raw, 1);
6007
+ }
6008
+ $field_parts = explode("|", $field_raw);
6009
+ //proceed if the first part, which is the label, is non-empty
6010
+ if ( trim($field_parts[0]) != "" ) {
6011
+ //get type, if exists, in order to adjust defaults
6012
+ $type_key = -1;
6013
+ $new_type = "";
6014
+ foreach ( $field_parts as $key => $part ) {
6015
+ $part = ltrim($part);
6016
+ $flag = substr($part, 0, 2);
6017
+ $val = substr($part, 2);
6018
+ if ( $flag == "t:" && $key > 0 && array_key_exists($val, $defaults) ) {
6019
+ $new_type = $val;
6020
+ $type_key = $key;
6021
+ break;
6022
+ }
6023
+ }
6024
+ if ( $new_type != "" ) {
6025
+ $fieldprops = $defaults[$new_type];
6026
+ unset($field_parts[$type_key]);
6027
+ }
6028
+ //store label
6029
+ $fieldprops["label"] = trim($field_parts[0]);
6030
+ unset($field_parts[0]);
6031
+ //get other properties
6032
+ foreach ( $field_parts as $part ) {
6033
+ $part = ltrim($part);
6034
+ $flag = substr($part, 0, 2);
6035
+ $val = "".substr($part, 2);
6036
+ if ( $flag == "s:" ) $fieldprops["labelposition"] = $val;
6037
+ elseif ( $flag == "r:" ) $fieldprops["required"] = ( $val == "1" );
6038
+ elseif ( $flag == "a:" ) $fieldprops["donotautocomplete"] = ( $val == "1" );
6039
+ elseif ( $flag == "v:" ) $fieldprops["validate"] = ( $val == "1" );
6040
+ elseif ( $flag == "d:" ) $fieldprops["default"] = $val;
6041
+ elseif ( $flag == "l:" ) $fieldprops["data"] = $val;
6042
+ elseif ( $flag == "g:" ) $fieldprops["group"] = $val;
6043
+ elseif ( $flag == "f:" ) $fieldprops["format"] = $val;
6044
+ elseif ( $flag == "p:" ) $fieldprops["hintposition"] = $val;
6045
+ elseif ( $flag == "h:" ) $fieldprops["typehook"] = ( $val == "1" );
6046
+ }
6047
+ array_push($fields, $fieldprops);
6048
+ }
6049
+ }
6050
+
6051
+ return $fields;
6052
+ }
6053
+
6054
+ /**
6055
+ * Checke and Remove Honeypot Fields.
6056
+ *
6057
+ * The plugin uses honeypot userdata fields as an additional security measure
6058
+ * against bots. A honeypot is a field which is not visible to the user, but it
6059
+ * can be filled with a value. A human will not see the field, so it will not
6060
+ * fill it with data. On the other hand, a bot does not care about visibility.
6061
+ * If the field has a common name, like 'url' or 'website' it will think that it
6062
+ * is a normal field and will fill it with data. In this case the upload will
6063
+ * fail silently (the bot will think that it succeeded). If the honeypot field
6064
+ * is empty, then the upload will continue normally, however it will be removed
6065
+ * from userdata fields list because it is not necessary anymore.
6066
+ *
6067
+ * @since 4.10.1
6068
+ *
6069
+ * @param array $userdata_fields An array of userdata fields.
6070
+ * @param string $post_key A string to locate the value of the honeypot field
6071
+ * in received POST parameters.
6072
+ *
6073
+ * @return bool True if the honeypot field is filled, false otherwise.
6074
+ */
6075
+ function wfu_check_remove_honeypot_fields(&$userdata_fields, $post_key) {
6076
+ //check if honeypot userdata fields have been added to the form and if they
6077
+ //contain any data
6078
+ $honeypot_filled = false;
6079
+ foreach ( $userdata_fields as $userdata_key => $userdata_field ) {
6080
+ if ( $userdata_field["type"] == "honeypot" ) {
6081
+ $val = ( isset($_POST[$post_key.$userdata_key]) ? $_POST[$post_key.$userdata_key] : "" );
6082
+ //if a non-zero value has been passed to the server, this means
6083
+ //that it has been filled by a bot
6084
+ if ( $val != "" ) {
6085
+ $honeypot_filled = true;
6086
+ break;
6087
+ }
6088
+ //if the honeypot field is empty then remove it from
6089
+ //userdata_fields array because we do not want to be stored
6090
+ else unset($userdata_fields[$userdata_key]);
6091
+ }
6092
+ }
6093
+
6094
+ //if any honeypot field has been filled then return true to denote that
6095
+ //the upload must be aborted
6096
+ return $honeypot_filled;
6097
+ }
6098
+
6099
+ //************************* Cookie Functions ***********************************
6100
+
6101
+ /**
6102
+ * Read Session Cookie.
6103
+ *
6104
+ * This function reads the session cookie of the plugin that is used to store
6105
+ * user state information when User State handler is set to 'dboption'.
6106
+ *
6107
+ * @since 4.12.0
6108
+ *
6109
+ * @return string The session ID.
6110
+ */
6111
+ function wfu_get_session_cookie() {
6112
+ return isset($_COOKIE[WPFILEUPLOAD_COOKIE]) ? wfu_sanitize_code(substr($_COOKIE[WPFILEUPLOAD_COOKIE], 0, 32)) : "";
6113
+ }
6114
+
6115
+ /**
6116
+ * Set Session Cookie.
6117
+ *
6118
+ * This function sets the session cookie of the plugin that is used to store
6119
+ * user state information when User State handler is set to 'dboption'. This
6120
+ * function generates a session ID that composes of a random 32-digit string.
6121
+ *
6122
+ * @since 4.12.0
6123
+ *
6124
+ * @redeclarable
6125
+ */
6126
+ function wfu_set_session_cookie() {
6127
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6128
+ if ( !headers_sent() ) {
6129
+ $cookie = wfu_create_random_string(32);
6130
+ setcookie(
6131
+ WPFILEUPLOAD_COOKIE,
6132
+ $cookie,
6133
+ time() + intval(WFU_VAR("WFU_US_COOKIE_LIFE")) * 3600,
6134
+ COOKIEPATH ? COOKIEPATH : '/',
6135
+ COOKIE_DOMAIN,
6136
+ false,
6137
+ false
6138
+ );
6139
+ $_COOKIE[WPFILEUPLOAD_COOKIE] = $cookie;
6140
+ }
6141
+ }
6142
+
6143
+ //********************* User State Functions ***********************************
6144
+
6145
+ /**
6146
+ * Initialize User State.
6147
+ *
6148
+ * This function initializes the user state. If user state handler is 'dboption'
6149
+ * then it sets the session cookie. If it is 'session' it starts the session
6150
+ * now or on demand, depending on 'WFU_US_SESSION_LEGACY' variable.
6151
+ *
6152
+ * @since 4.12.0
6153
+ *
6154
+ * @global string $wfu_user_state_handler The defined User State handler.
6155
+ *
6156
+ * @redeclarable
6157
+ */
6158
+ function wfu_initialize_user_state() {
6159
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6160
+ global $wfu_user_state_handler;
6161
+ if ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "cookies" ) {
6162
+ if ( wfu_get_session_cookie() == "" ) wfu_set_session_cookie();
6163
+ }
6164
+ elseif ( WFU_VAR("WFU_US_SESSION_LEGACY") == "true" && !headers_sent() && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) ) { session_start(); }
6165
+ }
6166
+
6167
+ /**
6168
+ * Check if User State Variable Exists.
6169
+ *
6170
+ * This function checks if a variable exists in User State.
6171
+ *
6172
+ * @since 4.3.2
6173
+ *
6174
+ * @global string $wfu_user_state_handler The defined User State handler.
6175
+ *
6176
+ * @redeclarable
6177
+ *
6178
+ * @param string $var The variable to check.
6179
+ *
6180
+ * @return bool True if the variable exists, false otherwise.
6181
+ */
6182
+ function WFU_USVAR_exists($var) {
6183
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6184
+ global $wfu_user_state_handler;
6185
+ if ( $wfu_user_state_handler == "dboption" )
6186
+ return ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USVAR_exists_dboption($var) : WFU_USVAR_exists_dboption_old($var) );
6187
+ else return WFU_USVAR_exists_session($var);
6188
+ }
6189
+
6190
+ /**
6191
+ * Get Variable From User State.
6192
+ *
6193
+ * This function gets the value of a variable from User State.
6194
+ *
6195
+ * @since 4.3.2
6196
+ *
6197
+ * @global string $wfu_user_state_handler The defined User State handler.
6198
+ *
6199
+ * @redeclarable
6200
+ *
6201
+ * @param string $var The variable to get.
6202
+ *
6203
+ * @return mixed The value of the variable.
6204
+ */
6205
+ function WFU_USVAR($var) {
6206
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6207
+ global $wfu_user_state_handler;
6208
+ if ( $wfu_user_state_handler == "dboption" )
6209
+ return ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USVAR_dboption($var) : WFU_USVAR_dboption_old($var) );
6210
+ else return WFU_USVAR_session($var);
6211
+ }
6212
+
6213
+ /**
6214
+ * Get All User State Variables.
6215
+ *
6216
+ * This function gets the values of all User State variables.
6217
+ *
6218
+ * @since 4.3.2
6219
+ *
6220
+ * @global string $wfu_user_state_handler The defined User State handler.
6221
+ *
6222
+ * @redeclarable
6223
+ *
6224
+ * @return array An array of all User State variables.
6225
+ */
6226
+ function WFU_USALL() {
6227
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6228
+ global $wfu_user_state_handler;
6229
+ if ( $wfu_user_state_handler == "dboption" )
6230
+ return ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USALL_dboption() : WFU_USALL_dboption_old() );
6231
+ else return WFU_USALL_session();
6232
+ }
6233
+
6234
+ /**
6235
+ * Store Variable In User State.
6236
+ *
6237
+ * This function stores the value of a variable in User State.
6238
+ *
6239
+ * @since 4.3.2
6240
+ *
6241
+ * @global string $wfu_user_state_handler The defined User State handler.
6242
+ *
6243
+ * @redeclarable
6244
+ *
6245
+ * @param string $var The variable to store.
6246
+ * @param mixed $value The value of the variable.
6247
+ */
6248
+ function WFU_USVAR_store($var, $value) {
6249
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6250
+ global $wfu_user_state_handler;
6251
+ if ( $wfu_user_state_handler == "dboption" )
6252
+ ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USVAR_store_dboption($var, $value) : WFU_USVAR_store_dboption_old($var, $value) );
6253
+ else WFU_USVAR_store_session($var, $value);
6254
+ }
6255
+
6256
+ /**
6257
+ * Remove Variable From User State.
6258
+ *
6259
+ * This function removes a variable from User State.
6260
+ *
6261
+ * @since 4.3.2
6262
+ *
6263
+ * @global string $wfu_user_state_handler The defined User State handler.
6264
+ *
6265
+ * @redeclarable
6266
+ *
6267
+ * @param string $var The variable to remove.
6268
+ */
6269
+ function WFU_USVAR_unset($var) {
6270
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6271
+ global $wfu_user_state_handler;
6272
+ if ( $wfu_user_state_handler == "dboption" )
6273
+ ( WFU_VAR("WFU_US_DBOPTION_USEOLD") == "false" ? WFU_USVAR_unset_dboption($var) : WFU_USVAR_unset_dboption_old($var) );
6274
+ else WFU_USVAR_unset_session($var);
6275
+ }
6276
+
6277
+ /**
6278
+ * Check if Session Variable Exists.
6279
+ *
6280
+ * This function checks if a variable exists in Session.
6281
+ *
6282
+ * @since 4.4.0
6283
+ *
6284
+ * @param string $var The variable to check.
6285
+ *
6286
+ * @return bool True if the variable exists, false otherwise.
6287
+ */
6288
+ function WFU_USVAR_exists_session($var) {
6289
+ $session_id = session_id();
6290
+ $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6291
+ if ( $open_session ) session_start();
6292
+ $exists = isset($_SESSION[$var]);
6293
+ if ( $open_session ) session_write_close();
6294
+ return $exists;
6295
+ }
6296
+
6297
+ /**
6298
+ * Get Variable From Session.
6299
+ *
6300
+ * This function gets the value of a variable from Session.
6301
+ *
6302
+ * @since 4.4.0
6303
+ *
6304
+ * @param string $var The variable to get.
6305
+ *
6306
+ * @return mixed The value of the variable.
6307
+ */
6308
+ function WFU_USVAR_session($var) {
6309
+ $session_id = session_id();
6310
+ $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6311
+ if ( $open_session ) session_start();
6312
+ $value = $_SESSION[$var];
6313
+ if ( $open_session ) session_write_close();
6314
+ return $value;
6315
+ }
6316
+
6317
+ /**
6318
+ * Get All Session Variables.
6319
+ *
6320
+ * This function gets the values of all Session variables.
6321
+ *
6322
+ * @since 4.4.0
6323
+ *
6324
+ * @return array An array of all Session variables.
6325
+ */
6326
+ function WFU_USALL_session() {
6327
+ $session_id = session_id();
6328
+ $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6329
+ if ( $open_session ) session_start();
6330
+ $all = $_SESSION;
6331
+ if ( $open_session ) session_write_close();
6332
+ return $all;
6333
+ }
6334
+
6335
+ /**
6336
+ * Store Variable In Session.
6337
+ *
6338
+ * This function stores the value of a variable in Session.
6339
+ *
6340
+ * @since 4.4.0
6341
+ *
6342
+ * @param string $var The variable to store.
6343
+ * @param mixed $value The value of the variable.
6344
+ */
6345
+ function WFU_USVAR_store_session($var, $value) {
6346
+ $session_id = session_id();
6347
+ $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6348
+ if ( $open_session ) session_start();
6349
+ $_SESSION[$var] = $value;
6350
+ if ( $open_session ) session_write_close();
6351
+ }
6352
+
6353
+ /**
6354
+ * Remove Variable From Session.
6355
+ *
6356
+ * This function removes a variable from Session.
6357
+ *
6358
+ * @since 4.4.0
6359
+ *
6360
+ * @param string $var The variable to remove.
6361
+ */
6362
+ function WFU_USVAR_unset_session($var) {
6363
+ $session_id = session_id();
6364
+ $open_session = ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) );
6365
+ if ( $open_session ) session_start();
6366
+ unset($_SESSION[$var]);
6367
+ if ( $open_session ) session_write_close();
6368
+ }
6369
+
6370
+ /**
6371
+ * Get Session ID.
6372
+ *
6373
+ * This function gets session ID depending on the user state handler and
6374
+ * relevant advanced variables.
6375
+ *
6376
+ * @since 4.12.0
6377
+ *
6378
+ * @global string $wfu_user_state_handler The defined User State handler.
6379
+ *
6380
+ * @return string The Session ID.
6381
+ */
6382
+ function wfu_get_session_id() {
6383
+ global $wfu_user_state_handler;
6384
+ $key = "";
6385
+ if ( ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "session" ) || $wfu_user_state_handler != "dboption" ) {
6386
+ $key = session_id();
6387
+ if ( WFU_VAR("WFU_US_SESSION_LEGACY") != "true" && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( session_id() == "" ) ) ) {
6388
+ session_start();
6389
+ $key = session_id();
6390
+ session_write_close();
6391
+ }
6392
+ }
6393
+ elseif ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "cookies" )
6394
+ $key = wfu_get_session_cookie();
6395
+ return $key;
6396
+ }
6397
+
6398
+ /**
6399
+ * Flatten Session ID.
6400
+ *
6401
+ * This function removes dots and other symbols from session ID.
6402
+ *
6403
+ * @since 4.4.0
6404
+ *
6405
+ * @return string Flattened Session ID.
6406
+ */
6407
+ function wfu_get_safe_session_id() {
6408
+ return preg_replace("/[^a-z0-9_]/", "", strtolower(wfu_get_session_id()));
6409
+ }
6410
+
6411
+ /**
6412
+ * Get DB Option Data.
6413
+ *
6414
+ * This function gets User State data for a specific session, stored in the
6415
+ * website's database.
6416
+ *
6417
+ * @since 4.4.0
6418
+ *
6419
+ * @param string $id The Session ID.
6420
+ * @param string $default Optional. Default value for the data.
6421
+ * @param string $type Optional. The type of data value.
6422
+ *
6423
+ * @return array The DB Option data.
6424
+ */
6425
+ function wfu_get_US_dboption_data($id, $default = false, $type = "array") {
6426
+ if ( $id == "" ) return false;
6427
+ return wfu_get_option("wfu_userstate_".$id, $default, $type);
6428
+ }
6429
+
6430
+ /**
6431
+ * Update DB Option Time.
6432
+ *
6433
+ * This function updates the time that DB Option data of a specific Session
6434
+ * where last used.
6435
+ *
6436
+ * @since 4.4.0
6437
+ *
6438
+ * @param string $id The Session ID.
6439
+ */
6440
+ function wfu_update_US_dboption_time($id) {
6441
+ $list = wfu_get_option("wfu_userstate_list", array());
6442
+ $list[$id] = time();
6443
+ wfu_update_option("wfu_userstate_list", $list);
6444
+ }
6445
+
6446
+ /**
6447
+ * Check if Variable Exists in DB Option (old handler).
6448
+ *
6449
+ * This function checks if a variable exists in DB Option.
6450
+ *
6451
+ * @since 4.4.0
6452
+ *
6453
+ * @param string $var The variable to check.
6454
+ *
6455
+ * @return bool True if the variable exists, false otherwise.
6456
+ */
6457
+ function WFU_USVAR_exists_dboption_old($var) {
6458
+ $id = wfu_get_safe_session_id();
6459
+ $data = wfu_get_US_dboption_data($id);
6460
+ if ( $data === false ) return false;
6461
+ wfu_update_US_dboption_time($id);
6462
+ return isset($data[$var]);
6463
+ }
6464
+
6465
+ /**
6466
+ * Check if Variable Exists in DB Option.
6467
+ *
6468
+ * This function checks if a variable exists in DB Option.
6469
+ *
6470
+ * @since 4.4.0
6471
+ *
6472
+ * @param string $var The variable to check.
6473
+ *
6474
+ * @return bool True if the variable exists, false otherwise.
6475
+ */
6476
+ function WFU_USVAR_exists_dboption($var) {
6477
+ $id = wfu_get_safe_session_id();
6478
+ if ( $id == "" ) return false;
6479
+ $exists = wfu_option_item_exists("wfu_userstate_".$id, $var);
6480
+ wfu_update_US_dboption_time($id);
6481
+ if ( $exists === null ) return false;
6482
+ else return $exists;
6483
+ }
6484
+
6485
+ /**
6486
+ * Get Variable From DB Option (old handler).
6487
+ *
6488
+ * This function gets the value of a variable from DB Option.
6489
+ *
6490
+ * @since 4.4.0
6491
+ *
6492
+ * @param string $var The variable to get.
6493
+ *
6494
+ * @return mixed The value of the variable.
6495
+ */
6496
+ function WFU_USVAR_dboption_old($var) {
6497
+ $id = wfu_get_safe_session_id();
6498
+ $data = wfu_get_US_dboption_data($id);
6499
+ if ( $data === false ) return "";
6500
+ wfu_update_US_dboption_time($id);
6501
+ return $data[$var];
6502
+ }
6503
+
6504
+ /**
6505
+ * Get Variable From DB Option.
6506
+ *
6507
+ * This function gets the value of a variable from DB Option.
6508
+ *
6509
+ * @since 4.4.0
6510
+ *
6511
+ * @param string $var The variable to get.
6512
+ *
6513
+ * @return mixed The value of the variable.
6514
+ */
6515
+ function WFU_USVAR_dboption($var) {
6516
+ $id = wfu_get_safe_session_id();
6517
+ if ( $id == "" ) return "";
6518
+ $value = wfu_get_option_item("wfu_userstate_".$id, $var);
6519
+ wfu_update_US_dboption_time($id);
6520
+ if ( $value === null ) return "";
6521
+ else return wfu_decode_array_from_string($value);
6522
+ }
6523
+
6524
+ /**
6525
+ * Get All DB Option Variables (old handler).
6526
+ *
6527
+ * This function gets the values of all DB Option variables.
6528
+ *
6529
+ * @since 4.4.0
6530
+ *
6531
+ * @return array An array of all DB Option variables.
6532
+ */
6533
+ function WFU_USALL_dboption_old() {
6534
+ $id = wfu_get_safe_session_id();
6535
+ $data = wfu_get_US_dboption_data($id);
6536
+ if ( $data === false ) return array();
6537
+ wfu_update_US_dboption_time($id);
6538
+ return $data;
6539
+ }
6540
+
6541
+ /**
6542
+ * Get All DB Option Variables.
6543
+ *
6544
+ * This function gets the values of all DB Option variables.
6545
+ *
6546
+ * @since 4.4.0
6547
+ *
6548
+ * @return array An array of all DB Option variables.
6549
+ */
6550
+ function WFU_USALL_dboption() {
6551
+ $id = wfu_get_safe_session_id();
6552
+ $data = wfu_get_US_dboption_data($id, false, "string");
6553
+ if ( $data === null ) return array();
6554
+ wfu_update_US_dboption_time($id);
6555
+ $arr = preg_split("/\[([^\]]*\][^{]*){[^}]*}/", $data, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
6556
+ $data_arr = array();
6557
+ foreach ( $arr as $item ) {
6558
+ $parts = explode("]", $item);
6559
+ if ( count($parts) == 2 )
6560
+ $data_arr[$parts[0]] = wfu_decode_array_from_string($parts[1]);
6561
+ }
6562
+ return $data_arr;
6563
+ }
6564
+
6565
+ /**
6566
+ * Store Variable In DB Option (old handler).
6567
+ *
6568
+ * This function stores the value of a variable in DB Option.
6569
+ *
6570
+ * @since 4.4.0
6571
+ *
6572
+ * @param string $var The variable to store.
6573
+ * @param mixed $value The value of the variable.
6574
+ */
6575
+ function WFU_USVAR_store_dboption_old($var, $value) {
6576
+ $id = wfu_get_safe_session_id();
6577
+ $data = wfu_get_US_dboption_data($id, array());
6578
+ if ( $data === false ) return;
6579
+ $data[$var] = $value;
6580
+ wfu_update_option("wfu_userstate_".$id, $data);
6581
+ wfu_update_US_dboption_time($id);
6582
+ wfu_update_US_dboption_list();
6583
+ }
6584
+
6585
+ /**
6586
+ * Store Variable In DB Option.
6587
+ *
6588
+ * This function stores the value of a variable in DB Option.
6589
+ *
6590
+ * @since 4.4.0
6591
+ *
6592
+ * @param string $var The variable to store.
6593
+ * @param mixed $value The value of the variable.
6594
+ */
6595
+ function WFU_USVAR_store_dboption($var, $value) {
6596
+ $id = wfu_get_safe_session_id();
6597
+ if ( $id == "" ) return;
6598
+ wfu_update_option_item("wfu_userstate_".$id, $var, wfu_encode_array_to_string($value));
6599
+ wfu_update_US_dboption_time($id);
6600
+ wfu_update_US_dboption_list();
6601
+ }
6602
+
6603
+ /**
6604
+ * Remove Variable From DB Option (old handler).
6605
+ *
6606
+ * This function removes a variable from DB Option.
6607
+ *
6608
+ * @since 4.4.0
6609
+ *
6610
+ * @param string $var The variable to remove.
6611
+ */
6612
+ function WFU_USVAR_unset_dboption_old($var) {
6613
+ $id = wfu_get_safe_session_id();
6614
+ $data = wfu_get_US_dboption_data($id);
6615
+ if ( $data === false ) return;
6616
+ unset($data[$var]);
6617
+ wfu_update_option("wfu_userstate_".$id, $data);
6618
+ wfu_update_US_dboption_time($id);
6619
+ }
6620
+
6621
+ /**
6622
+ * Remove Variable From DB Option.
6623
+ *
6624
+ * This function removes a variable from DB Option.
6625
+ *
6626
+ * @since 4.4.0
6627
+ *
6628
+ * @param string $var The variable to remove.
6629
+ */
6630
+ function WFU_USVAR_unset_dboption($var) {
6631
+ $id = wfu_get_safe_session_id();
6632
+ if ( $id == "" ) return;
6633
+ wfu_delete_option_item("wfu_userstate_".$id, $var);
6634
+ wfu_update_US_dboption_time($id);
6635
+ }
6636
+
6637
+ /**
6638
+ * Update DB Option List.
6639
+ *
6640
+ * This function checks when all DB Option Data were last used. DB Option data
6641
+ * that were last used before a long time, means that their Session has expired,
6642
+ * so they are not useful anymore and will be removed.
6643
+ *
6644
+ * @since 4.4.0
6645
+ */
6646
+ function wfu_update_US_dboption_list() {
6647
+ $last_check_interval = time() - wfu_get_option("wfu_userstate_list_last_check", 0);
6648
+ $limit = WFU_VAR("WFU_US_DBOPTION_CHECK");
6649
+ if ( $last_check_interval < $limit ) return;
6650
+
6651
+ $list = wfu_get_option("wfu_userstate_list", array());
6652
+ $changed = false;
6653
+ $limit = WFU_VAR("WFU_US_DBOPTION_LIFE");
6654
+ foreach ( $list as $id => $time ) {
6655
+ $interval = time() - $time;
6656
+ if ( $interval > $limit ) {
6657
+ $changed = true;
6658
+ unset($list[$id]);
6659
+ wfu_delete_option("wfu_userstate_".$id);
6660
+ }
6661
+ }
6662
+ if ( $changed ) wfu_update_option("wfu_userstate_list", $list);
6663
+ wfu_update_option("wfu_userstate_list_last_check", time());
6664
+ }
6665
+
6666
+ //********************* Javascript Related Functions ****************************************************************************************************
6667
+
6668
+ /**
6669
+ * Inject Javascript Code.
6670
+ *
6671
+ * This function generates HTML output for injecting Javascript code. After
6672
+ * execution of the code, the HTML output is erased leaving no traces.
6673
+ *
6674
+ * @since 3.3.0
6675
+ *
6676
+ * @param string $code The Javascript code to inject.
6677
+ *
6678
+ * @return string The HTML output.
6679
+ */
6680
+ function wfu_inject_js_code($code){
6681
+ $id = 'code_'.wfu_create_random_string(8);
6682
+ $html = '<div id="'.$id.'" style="display:none;"><script type="text/javascript">'.$code.'</script><script type="text/javascript">var div = document.getElementById("'.$id.'"); div.parentNode.removeChild(div);</script></div>';
6683
+
6684
+ return $html;
6685
+ }
6686
+
6687
+ //********************* Consent Functions ****************************************************************************************************
6688
+
6689
+ /**
6690
+ * Get Consent Status of User.
6691
+ *
6692
+ * This function gets the consent status of a user.
6693
+ *
6694
+ * @since 4.5.0
6695
+ *
6696
+ * @param WPUser $user The user to get its consent status.
6697
+ *
6698
+ * @return string The consent status of the user:
6699
+ * "1": the user has given its consent.
6700
+ * "0": the user has not given its consent.
6701
+ * "": the user has not answered to consent question.
6702
+ */
6703
+ function wfu_check_user_consent($user) {
6704
+ //returns empty string if user has not completed consent question yet, "1"
6705
+ //if user has given consent, "0" otherwise
6706
+ $result = "";
6707
+ if ( $user->ID > 0 ) {
6708
+ //check in user meta for consent
6709
+ $data = get_the_author_meta( 'WFU_Consent_Data', $user->ID );
6710
+ if ( $data && isset($data["consent_status"]) )
6711
+ $result = $data["consent_status"];
6712
+ }
6713
+ else {
6714
+ //check in user state for consent
6715
+ if ( WFU_USVAR_exists('WFU_Consent_Data') ) {
6716
+ $data = WFU_USVAR('WFU_Consent_Data');
6717
+ if ( isset($data["consent_status"]) )
6718
+ $result = $data["consent_status"];
6719
+ }
6720
+ }
6721
+
6722
+ return $result;
6723
+ }
6724
+
6725
+ /**
6726
+ * Update Consent Status of User From Front-End.
6727
+ *
6728
+ * This function updates the consent status of a user when asked through an
6729
+ * upload form. If user is logged in, then consent status is stored in its
6730
+ * profile. If the user is not logged in, then consent status is store in User
6731
+ * State.
6732
+ *
6733
+ * @since 4.5.0
6734
+ *
6735
+ * @param WPUser $user The user to store its consent status.
6736
+ * @param string $consent_result The new consent status. It can be "yes", "no"
6737
+ * or "".
6738
+ */
6739
+ function wfu_update_user_consent($user, $consent_result) {
6740
+ if ( $user->ID > 0 ) {
6741
+ //check in user meta for consent
6742
+ $data = get_the_author_meta( 'WFU_Consent_Data', $user->ID );
6743
+ if ( !$data ) $data = array();
6744
+ $data["consent_status"] = ( $consent_result == "yes" ? "1" : ( $consent_result == "no" ? "0" : "" ) );
6745
+ update_user_meta( $user->ID, 'WFU_Consent_Data', $data );
6746
+ }
6747
+ else {
6748
+ //check in user state for consent
6749
+ if ( WFU_USVAR_exists('WFU_Consent_Data') ) $data = WFU_USVAR('WFU_Consent_Data');
6750
+ else $data = array();
6751
+ $data["consent_status"] = ( $consent_result == "yes" ? "1" : ( $consent_result == "no" ? "0" : "" ) );
6752
+ WFU_USVAR_store( 'WFU_Consent_Data', $data );
6753
+ }
6754
+ }
6755
+
6756
+ /**
6757
+ * Show Consent Status Fields in User's Profile Page.
6758
+ *
6759
+ * This function outputs the HTML code of the consent status fields shown in
6760
+ * user's profile page.
6761
+ *
6762
+ * @since 4.5.0
6763
+ *
6764
+ * @param WPUser $user The involved user.
6765
+ */
6766
+ function wfu_show_consent_profile_fields($user) {
6767
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
6768
+ if ( $plugin_options["personaldata"] != "1" ) return;
6769
+
6770
+ $data = get_the_author_meta( 'WFU_Consent_Data', $user->ID );
6771
+ if ( !$data ) $data = array();
6772
+ if ( !isset($data["consent_status"]) ) $data["consent_status"] = "";
6773
+ $status = $data["consent_status"];
6774
+
6775
+ $echo_str = "\n\t".'<h3>'.esc_html__( 'Wordpress File Upload Consent Status', 'wp-file-upload' ).'</h3>';
6776
+ $echo_str .= "\n\t".'<table class="form-table">';
6777
+ $echo_str .= "\n\t\t".'<tr>';
6778
+ $echo_str .= "\n\t\t\t".'<th><label>'.esc_html__( 'Consent Status', 'wp-file-upload' ).'</label></th>';
6779
+ $echo_str .= "\n\t\t\t".'<td>';
6780
+ $echo_str .= "\n\t\t\t\t".'<label style="font-weight: bold;">'.( $status == "1" ? esc_html__( 'You have given your consent to store personal data.', 'wp-file-upload' ) : ( $status == "0" ? esc_html__( 'You have denied to store personal data.', 'wp-file-upload' ) : esc_html__( 'You have not answered to consent yet.', 'wp-file-upload' ) ) ).'</label>';
6781
+ $echo_str .= "\n\t\t\t".'</td>';
6782
+ $echo_str .= "\n\t\t".'</tr>';
6783
+ $echo_str .= "\n\t\t".'<tr>';
6784
+ $echo_str .= "\n\t\t\t".'<th></th>';
6785
+ $echo_str .= "\n\t\t\t".'<td>';
6786
+ $echo_str .= "\n\t\t\t\t".'<label>'.esc_html__( 'Change status to', 'wp-file-upload' ).'</label>';
6787
+ $echo_str .= "\n\t\t\t\t".'<select name="consent_status">';
6788
+ $echo_str .= "\n\t\t\t\t\t".'<option value="-1" selected="selected">'.esc_html__( 'No change', 'wp-file-upload' ).'</option>';
6789
+ if ( $status == "1" ) {
6790
+ $echo_str .= "\n\t\t\t\t\t".'<option value="0">'.esc_html__( 'Revoke Consent', 'wp-file-upload' ).'</option>';
6791
+ $echo_str .= "\n\t\t\t\t\t".'<option value="">'.esc_html__( 'Clear Consent', 'wp-file-upload' ).'</option>';
6792
+ }
6793
+ elseif ( $status == "0" ) {
6794
+ $echo_str .= "\n\t\t\t\t\t".'<option value="1">'.esc_html__( 'Give Consent', 'wp-file-upload' ).'</option>';
6795
+ $echo_str .= "\n\t\t\t\t\t".'<option value="">'.esc_html__( 'Clear Consent', 'wp-file-upload' ).'</option>';
6796
+ }
6797
+ if ( $status == "" ) {
6798
+ $echo_str .= "\n\t\t\t\t\t".'<option value="0">'.esc_html__( 'Revoke Consent', 'wp-file-upload' ).'</option>';
6799
+ $echo_str .= "\n\t\t\t\t\t".'<option value="1">'.esc_html__( 'Give Consent', 'wp-file-upload' ).'</option>';
6800
+ }
6801
+ $echo_str .= "\n\t\t\t\t".'</select>';
6802
+ $echo_str .= "\n\t\t\t".'</td>';
6803
+ $echo_str .= "\n\t\t".'</tr>';
6804
+ /*
6805
+ if ( current_user_can( 'manage_options' ) ) {
6806
+ $echo_str .= "\n\t\t".'<tr>';
6807
+ $echo_str .= "\n\t\t\t".'<th><label>'.esc_html__( 'Personal Data Operations', 'wp-file-upload' ).'</label></th>';
6808
+ $echo_str .= "\n\t\t\t".'<td>';
6809
+ $echo_str .= "\n\t\t\t\t".'<input id="wfu_download_file_nonce" type="hidden" value="'.wp_create_nonce('wfu_download_file_invoker').'" />';
6810
+ $echo_str .= "\n\t\t\t\t".'<button type="button" class="button" onclick="wfu_download_file(\'exportdata\', 1);">'.esc_html__( 'Export User Data', 'wp-file-upload' ).'</button>';
6811
+ $echo_str .= "\n\t\t\t".'</td>';
6812
+ $echo_str .= "\n\t\t".'</tr>';
6813
+ }*/
6814
+ $echo_str .= "\n\t".'</table>';
6815
+
6816
+ echo $echo_str;
6817
+ }
6818
+
6819
+ /**
6820
+ * Update Consent Status of User From Back-End.
6821
+ *
6822
+ * This function updates the consent status of a user from its User Profile
6823
+ * page.
6824
+ *
6825
+ * @since 4.5.0
6826
+ *
6827
+ * @param int $user_id The ID of the involved user.
6828
+ */
6829
+ function wfu_update_consent_profile_fields( $user_id ) {
6830
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
6831
+ if ( $plugin_options["personaldata"] != "1" ) return false;
6832
+
6833
+ if ( ! current_user_can( 'edit_user', $user_id ) ) {
6834
+ return false;
6835
+ }
6836
+
6837
+ $status = $_POST['consent_status'];
6838
+ if ( $status == '1' || $status == '0' || $status == '' ) {
6839
+ $data = get_the_author_meta( 'WFU_Consent_Data', $user_id );
6840
+ if ( !$data ) $data = array();
6841
+ $data["consent_status"] = $status;
6842
+ update_user_meta( $user_id, 'WFU_Consent_Data', $data );
6843
+ }
6844
+ }
6845
+
6846
+ //********************* Browser Functions ****************************************************************************************************
6847
+
6848
+ /**
6849
+ * Store Front-End File Viewer Shortcode Attributes.
6850
+ *
6851
+ * This function stores the shortcode attributes of a front-end file viewer in
6852
+ * User Space for future retrieval.
6853
+ *
6854
+ * @since 3.6.1
6855
+ *
6856
+ * @param string $params The front-end file viewer shortcode attributes.
6857
+ *
6858
+ * @return string A unique code representing the stored shortcode.
6859
+ */
6860
+ function wfu_safe_store_browser_params($params) {
6861
+ $code = wfu_create_random_string(16);
6862
+ $safe_storage = ( WFU_USVAR_exists('wfu_browser_actions_safe_storage') ? WFU_USVAR('wfu_browser_actions_safe_storage') : array() );
6863
+ $safe_storage[$code] = $params;
6864
+ WFU_USVAR_store('wfu_browser_actions_safe_storage', $safe_storage);
6865
+ return $code;
6866
+ }
6867
+
6868
+ /**
6869
+ * Retrieve Stored Front-End File Viewer Shortcode Attributes.
6870
+ *
6871
+ * This function retrieved stored shortcode attributes of a front-end file
6872
+ * viewer from User Space.
6873
+ *
6874
+ * @since 3.6.1
6875
+ *
6876
+ * @param string $code A unique code representing the stored shortcode.
6877
+ *
6878
+ * @return string The stored shortcode attributes.
6879
+ */
6880
+ function wfu_get_browser_params_from_safe($code) {
6881
+ //sanitize $code
6882
+ $code = wfu_sanitize_code($code);
6883
+ if ( $code == "" ) return false;
6884
+ //return params from session variable, if exists
6885
+ if ( !WFU_USVAR_exists('wfu_browser_actions_safe_storage') ) return false;
6886
+ $safe_storage = WFU_USVAR('wfu_browser_actions_safe_storage');
6887
+ if ( !isset($safe_storage[$code]) ) return false;
6888
+ return $safe_storage[$code];
6889
+ }
6890
+
6891
+ //********************* POST/GET Requests Functions ****************************************************************************************************
6892
+
6893
+ /**
6894
+ * Add Proxy in HTTP Request.
6895
+ *
6896
+ * This function adds proxy information inside an HTTP request configuration, if
6897
+ * proxy information is defined inside the website's configuration and if it is
6898
+ * active.
6899
+ *
6900
+ * @since 4.10.0
6901
+ *
6902
+ * @param array $config An HTTP request configuration structure.
6903
+ *
6904
+ * @return bool True if proxy is enabled and added, false otherwise.
6905
+ */
6906
+ function wfu_add_proxy_param(&$config) {
6907
+ //include proxy support
6908
+ $proxy = new \WP_HTTP_Proxy();
6909
+ $proxy_enabled = $proxy->is_enabled();
6910
+ if ( $proxy_enabled ) {
6911
+ $config['proxy']['http'] = 'http://'.( $proxy->use_authentication() ? $proxy->authentication().'@' : '' ).$proxy->host().":".$proxy->port();
6912
+ $config['proxy']['https'] = 'http://'.( $proxy->use_authentication() ? $proxy->authentication().'@' : '' ).$proxy->host().":".$proxy->port();
6913
+ //make sure that wildcard asterisks (*) are removed from bypass hosts
6914
+ //to make it compatible with Guzzle format
6915
+ if ( defined('WP_PROXY_BYPASS_HOSTS') ) $config['proxy']['no'] = preg_split('|,\s*|', str_replace('*', '', WP_PROXY_BYPASS_HOSTS));
6916
+ }
6917
+
6918
+ return $proxy_enabled;
6919
+ }
6920
+
6921
+ /**
6922
+ * Parse Socket HTTP Response.
6923
+ *
6924
+ * This function tries to decode an HTTP response received through sockets and
6925
+ * return the clean response data.
6926
+ *
6927
+ * @since 3.10.0
6928
+ *
6929
+ * @param string $response The raw sockets HTTP response.
6930
+ *
6931
+ * @return string The clean HTTP response data.
6932
+ */
6933
+ function wfu_decode_socket_response($response) {
6934
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6935
+ $ret = "";
6936
+ if (0 === strpos($response, 'HTTP/1.1 200 OK')) {
6937
+ $parts = preg_split("#\n\s*\n#Uis", $response);
6938
+ if ( count($parts) > 1 ) {
6939
+ $rawheader = strtolower(preg_replace("/\s/", "", $parts[0]));
6940
+ if ( strpos($rawheader, 'transfer-encoding:chunked') !== false ) {
6941
+ $ret = "";
6942
+ $pos = 0;
6943
+ while ( $pos < strlen($parts[1]) ) {
6944
+ $next = strpos($parts[1], "\r\n", $pos);
6945
+ $len = ( $next === false || $next == $pos ? 0 : hexdec(substr($parts[1], $pos, $next - $pos)) );
6946
+ if ( $len <= 0 ) break;
6947
+ $ret .= substr($parts[1], $next + 2, $len);
6948
+ $pos = $next + $len + 4;
6949
+ }
6950
+ }
6951
+ else $ret = $parts[1];
6952
+ }
6953
+ }
6954
+ return $ret;
6955
+ }
6956
+
6957
+ /**
6958
+ * Send POST Request.
6959
+ *
6960
+ * This function sends a POST request using the method defined in Post Method
6961
+ * option of the plugin's Settings. It is noted that the post request is
6962
+ * executed synchronously. The function will wait for the response and then it
6963
+ * will finish.
6964
+ *
6965
+ * @since 2.6.0
6966
+ *
6967
+ * @param string $url The destination URL of the request.
6968
+ * @param array $params Parameters to pass to the POST request.
6969
+ * @param bool $verifypeer Optional. Verify the peer for secure (SSL) requests.
6970
+ * @param bool $internal_request Optional. True if this is an internal request
6971
+ * to targetting /wp-admin area. In this case a username/password will
6972
+ * also be passed to the request if Dashboard is password protected.
6973
+ * @param int $timeout Optional. Timeout of the request in seconds.
6974
+ *
6975
+ * @return string The response of the POST request.
6976
+ */
6977
+ function wfu_post_request($url, $params, $verifypeer = true, $internal_request = false, $timeout = 0) {
6978
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
6979
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
6980
+ $default_args = array(
6981
+ 'url' => $url,
6982
+ 'params' => $params,
6983
+ 'verifypeer' => $verifypeer,
6984
+ 'internal_request' => $internal_request,
6985
+ 'timeout' => $timeout
6986
+ );
6987
+ //check proxy
6988
+ $proxy = new WP_HTTP_Proxy();
6989
+ if ( isset($plugin_options['postmethod']) && $plugin_options['postmethod'] == 'curl' ) {
6990
+ // POST request using CURL
6991
+ $ch = curl_init($url);
6992
+ $options = array(
6993
+ CURLOPT_POST => true,
6994
+ CURLOPT_POSTFIELDS => http_build_query($params),
6995
+ CURLOPT_HTTPHEADER => array(
6996
+ 'Content-Type: application/x-www-form-urlencoded'
6997
+ ),
6998
+ CURLINFO_HEADER_OUT => false,
6999
+ CURLOPT_HEADER => false,
7000
+ CURLOPT_RETURNTRANSFER => true,
7001
+ CURLOPT_SSL_VERIFYPEER => $verifypeer,
7002
+ CURLOPT_SSL_VERIFYHOST => ( $verifypeer ? CURLOPT_SSL_VERIFYHOST : false )
7003
+ );
7004
+ if ( $timeout > 0 ) $options[CURLOPT_TIMEOUT] = $timeout;
7005
+ //for internal requests to /wp-admin area that is password protected
7006
+ //authorization is required
7007
+ if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
7008
+ $options[CURLOPT_HTTPAUTH] = CURLAUTH_ANY;
7009
+ $options[CURLOPT_USERPWD] = WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD");
7010
+ }
7011
+ if ( WFU_VAR("WFU_RELAX_CURL_VERIFY_HOST") == "true" ) $options[CURLOPT_SSL_VERIFYHOST] = false;
7012
+ //configure cURL request for proxy
7013
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
7014
+ $options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
7015
+ $options[CURLOPT_PROXY] = $proxy->host().":".$proxy->port();
7016
+ if ( $proxy->use_authentication() ) {
7017
+ $options[CURLOPT_PROXYAUTH] = CURLAUTH_ANY;
7018
+ $options[CURLOPT_PROXYUSERPWD] = $proxy->authentication();
7019
+ }
7020
+ }
7021
+ /**
7022
+ * Customize POST Request Options.
7023
+ *
7024
+ * This filter allows custom actions to modify the POST request options
7025
+ * before the request is sent.
7026
+ *
7027
+ * @since 4.10.0
7028
+ *
7029
+ * @param array|string $options An array of POST options or request
7030
+ * string.
7031
+ * @param string $method The POST method. It can be 'fopen', 'curl' or
7032
+ * 'sockets'.
7033
+ * @param array $default_args {
7034
+ * Parameters of the POST request.
7035
+ *
7036
+ * @type string $url Destination URL.
7037
+ * @type array $params The POST parameters.
7038
+ * @type bool $verifypeer True if peer needs to be verified.
7039
+ * @type bool $internal_request True if this is an internal
7040
+ * request (sent back to the website).
7041
+ * @type int $timeout The request timeout in seconds.
7042
+ * }
7043
+ */
7044
+ $options = apply_filters("_wfu_post_request_options", $options, "curl", $default_args);
7045
+ curl_setopt_array($ch, $options);
7046
+ $result = curl_exec($ch);
7047
+ curl_close ($ch);
7048
+ return $result;
7049
+ }
7050
+ elseif ( isset($plugin_options['postmethod']) && $plugin_options['postmethod'] == 'socket' ) {
7051
+ // POST request using sockets
7052
+ $scheme = "";
7053
+ $port = 80;
7054
+ $errno = 0;
7055
+ $errstr = '';
7056
+ $ret = '';
7057
+ $url_parts = parse_url($url);
7058
+ $host = $url_parts['host'];
7059
+ $socket_host = $host;
7060
+ $path = $url_parts['path'];
7061
+ if ( $url_parts['scheme'] == 'https' ) {
7062
+ $scheme = "ssl://";
7063
+ $port = 443;
7064
+ if ( $timeout == 0 ) $timeout = 30;
7065
+ }
7066
+ elseif ( $url['scheme'] != 'http' ) return '';
7067
+ //configure sockets request for proxy
7068
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
7069
+ $scheme = "";
7070
+ $socket_host = $proxy->host();
7071
+ $port = $proxy->port();
7072
+ $path = $url;
7073
+ }
7074
+ if ( $verifypeer ) $handle = fsockopen($scheme.$socket_host, $port, $errno, $errstr, ($timeout == 0 ? ini_get("default_socket_timeout") : $timeout));
7075
+ else {
7076
+ $context = stream_context_create(array(
7077
+ 'ssl' => array(
7078
+ 'verify_peer' => false,
7079
+ 'verify_peer_name' => false
7080
+ )));
7081
+ $handle = stream_socket_client($scheme.$socket_host.":".$port, $errno, $errstr, ($timeout == 0 ? ini_get("default_socket_timeout") : $timeout), STREAM_CLIENT_CONNECT, $context);
7082
+ }
7083
+ if ( $errno !== 0 || $errstr !== '' ) $handle = false;
7084
+ if ( $handle !== false ) {
7085
+ $content = http_build_query($params);
7086
+ $request = "POST " . $path . " HTTP/1.1\r\n";
7087
+ $request .= "Host: " . $host . "\r\n";
7088
+ $request .= "Content-Type: application/x-www-form-urlencoded\r\n";
7089
+ //for internal requests to /wp-admin area that is password protected
7090
+ //authorization is required
7091
+ if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" )
7092
+ $request .= "Authorization: Basic ".base64_encode(WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD"))."\r\n";
7093
+ //add proxy authentication if exists and is required
7094
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) && $proxy->use_authentication() )
7095
+ $request .= $proxy->authentication_header()."\r\n";
7096
+ $request .= "Content-length: " . strlen($content) . "\r\n";
7097
+ $request .= "Connection: close\r\n\r\n";
7098
+ $request .= $content . "\r\n\r\n";
7099
+ /** This filter is explained above. */
7100
+ $request = apply_filters("_wfu_post_request_options", $request, "socket", $default_args);
7101
+ fwrite($handle, $request, strlen($request));
7102
+ $response = '';
7103
+ while ( !feof($handle) ) {
7104
+ $response .= fgets($handle, 4096);
7105
+ }
7106
+ fclose($handle);
7107
+ $ret = wfu_decode_socket_response($response);
7108
+ }
7109
+ return $ret;
7110
+ }
7111
+ else {
7112
+ // POST request using file_get_contents
7113
+ if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
7114
+ $url = preg_replace("/^(http|https):\/\//", "$1://".WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD")."@", $url);
7115
+ }
7116
+ $peer_key = version_compare(PHP_VERSION, '5.6.0', '<') ? 'CN_name' : 'peer_name';
7117
+ $http_array = array(
7118
+ 'method' => 'POST',
7119
+ 'header' => "Content-type: application/x-www-form-urlencoded\r\n",
7120
+ 'content' => http_build_query($params)
7121
+ );
7122
+ //configure fopen request for proxy
7123
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
7124
+ $http_array['proxy'] = 'tcp://'.$proxy->host().":".$proxy->port();
7125
+ if ( $proxy->use_authentication() )
7126
+ $http_array['header'] .= $proxy->authentication_header()."\r\n";
7127
+ }
7128
+ if ( $timeout > 0 ) $http_array['timeout'] = $timeout;
7129
+ //for internal requests to /wp-admin area that is password protected
7130
+ //authorization is required
7131
+ if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
7132
+ $http_array['header'] .= "Authorization: Basic ".base64_encode(WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD"))."\r\n";
7133
+ }
7134
+ $context_params = array( 'http' => $http_array );
7135
+ if ( !$verifypeer ) $context_params['ssl'] = array( 'verify_peer' => false, 'allow_self_signed' => true, 'verify_peer_name' => false );
7136
+ /** This filter is explained above. */
7137
+ $context_params = apply_filters("_wfu_post_request_options", $context_params, "fopen", $default_args);
7138
+ $context = stream_context_create($context_params);
7139
+ return file_get_contents($url, false, $context);
7140
+ }
7141
+ }
7142
+
7143
+ /**
7144
+ * Send GET Request.
7145
+ *
7146
+ * This function sends a GET request using the method defined in Post Method
7147
+ * option of the plugin's Settings. It is noted that the get request is
7148
+ * executed synchronously. The function will wait for the response and then it
7149
+ * will finish.
7150
+ *
7151
+ * @since 4.13.0
7152
+ *
7153
+ * @param string $url The destination URL of the request.
7154
+ * @param array $params Optional. Parameters to pass to the GET request.
7155
+ * @param bool $verifypeer Optional. Verify the peer for secure (SSL) requests.
7156
+ * @param bool $internal_request Optional. True if this is an internal request
7157
+ * to targetting /wp-admin area. In this case a username/password will
7158
+ * also be passed to the request if Dashboard is password protected.
7159
+ * @param int $timeout Optional. Timeout of the request in seconds.
7160
+ *
7161
+ * @return string The response of the GET request.
7162
+ */
7163
+ function wfu_get_request($url, $params = array(), $verifypeer = true, $internal_request = false, $timeout = 0) {
7164
+ $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
7165
+ $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
7166
+ $default_args = array(
7167
+ 'url' => $url,
7168
+ 'params' => $params,
7169
+ 'verifypeer' => $verifypeer,
7170
+ 'internal_request' => $internal_request,
7171
+ 'timeout' => $timeout
7172
+ );
7173
+ $http_params = http_build_query($params);
7174
+ $url .= ( $http_params == "" ? "" : "?".$http_params );
7175
+ //check proxy
7176
+ $proxy = new WP_HTTP_Proxy();
7177
+ if ( isset($plugin_options['postmethod']) && $plugin_options['postmethod'] == 'curl' ) {
7178
+ // GET request using CURL
7179
+ $ch = curl_init($url);
7180
+ $options = array(
7181
+ CURLINFO_HEADER_OUT => false,
7182
+ CURLOPT_HEADER => false,
7183
+ CURLOPT_RETURNTRANSFER => true,
7184
+ CURLOPT_SSL_VERIFYPEER => $verifypeer,
7185
+ CURLOPT_SSL_VERIFYHOST => ( $verifypeer ? CURLOPT_SSL_VERIFYHOST : false )
7186
+ );
7187
+ if ( $timeout > 0 ) $options[CURLOPT_TIMEOUT] = $timeout;
7188
+ //for internal requests to /wp-admin area that is password protected
7189
+ //authorization is required
7190
+ if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
7191
+ $options[CURLOPT_HTTPAUTH] = CURLAUTH_ANY;
7192
+ $options[CURLOPT_USERPWD] = WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD");
7193
+ }
7194
+ if ( WFU_VAR("WFU_RELAX_CURL_VERIFY_HOST") == "true" ) $options[CURLOPT_SSL_VERIFYHOST] = false;
7195
+ //configure cURL request for proxy
7196
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
7197
+ $options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP;
7198
+ $options[CURLOPT_PROXY] = $proxy->host().":".$proxy->port();
7199
+ if ( $proxy->use_authentication() ) {
7200
+ $options[CURLOPT_PROXYAUTH] = CURLAUTH_ANY;
7201
+ $options[CURLOPT_PROXYUSERPWD] = $proxy->authentication();
7202
+ }
7203
+ }
7204
+ /**
7205
+ * Customize GET Request Options.
7206
+ *
7207
+ * This filter allows custom actions to modify the GET request options
7208
+ * before the request is sent.
7209
+ *
7210
+ * @since 4.13.0
7211
+ *
7212
+ * @param array $options|string An array of GET options or request
7213
+ * string.
7214
+ * @param string $method The GET method. It can be 'fopen', 'curl' or
7215
+ * 'sockets'.
7216
+ * @param array $default_args {
7217
+ * Parameters of the GET request.
7218
+ *
7219
+ * @type string $url Destination URL.
7220
+ * @type array $params The GET parameters.
7221
+ * @type bool $verifypeer True if peer needs to be verified.
7222
+ * @type bool $internal_request True if this is an internal
7223
+ * request (sent back to the website).
7224
+ * @type int $timeout The request timeout in seconds.
7225
+ * }
7226
+ */
7227
+ $options = apply_filters("_wfu_get_request_options", $options, "curl", $default_args);
7228
+ curl_setopt_array($ch, $options);
7229
+ $result = curl_exec($ch);
7230
+ curl_close ($ch);
7231
+ return $result;
7232
+ }
7233
+ elseif ( isset($plugin_options['postmethod']) && $plugin_options['postmethod'] == 'socket' ) {
7234
+ // GET request using sockets
7235
+ $scheme = "";
7236
+ $port = 80;
7237
+ $errno = 0;
7238
+ $errstr = '';
7239
+ $ret = '';
7240
+ $url_parts = parse_url($url);
7241
+ $host = $url_parts['host'];
7242
+ $socket_host = $host;
7243
+ $path = $url_parts['path'];
7244
+ if ( $url_parts['scheme'] == 'https' ) {
7245
+ $scheme = "ssl://";
7246
+ $port = 443;
7247
+ if ( $timeout == 0 ) $timeout = 30;
7248
+ }
7249
+ elseif ( $url['scheme'] != 'http' ) return '';
7250
+ //configure sockets request for proxy
7251
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
7252
+ $scheme = "";
7253
+ $socket_host = $proxy->host();
7254
+ $port = $proxy->port();
7255
+ $path = $url;
7256
+ }
7257
+ if ( $verifypeer ) $handle = fsockopen($scheme.$socket_host, $port, $errno, $errstr, ($timeout == 0 ? ini_get("default_socket_timeout") : $timeout));
7258
+ else {
7259
+ $context = stream_context_create(array(
7260
+ 'ssl' => array(
7261
+ 'verify_peer' => false,
7262
+ 'verify_peer_name' => false
7263
+ )));
7264
+ $handle = stream_socket_client($scheme.$socket_host.":".$port, $errno, $errstr, ($timeout == 0 ? ini_get("default_socket_timeout") : $timeout), STREAM_CLIENT_CONNECT, $context);
7265
+ }
7266
+ if ( $errno !== 0 || $errstr !== '' ) $handle = false;
7267
+ if ( $handle !== false ) {
7268
+ $request = "GET " . $path . " HTTP/1.1\r\n";
7269
+ $request .= "Host: " . $host . "\r\n";
7270
+ //for internal requests to /wp-admin area that is password protected
7271
+ //authorization is required
7272
+ if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" )
7273
+ $request .= "Authorization: Basic ".base64_encode(WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD"))."\r\n";
7274
+ //add proxy authentication if exists and is required
7275
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) && $proxy->use_authentication() )
7276
+ $request .= $proxy->authentication_header()."\r\n";
7277
+ $request .= "Connection: close\r\n\r\n";
7278
+ $request .= $content . "\r\n\r\n";
7279
+ /** This filter is explained above. */
7280
+ $request = apply_filters("_wfu_get_request_options", $request, "socket", $default_args);
7281
+ fwrite($handle, $request, strlen($request));
7282
+ $response = '';
7283
+ while ( !feof($handle) ) {
7284
+ $response .= fgets($handle, 4096);
7285
+ }
7286
+ fclose($handle);
7287
+ $ret = wfu_decode_socket_response($response);
7288
+ }
7289
+ return $ret;
7290
+ }
7291
+ else {
7292
+ // GET request using file_get_contents
7293
+ if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
7294
+ $url = preg_replace("/^(http|https):\/\//", "$1://".WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD")."@", $url);
7295
+ }
7296
+ $peer_key = version_compare(PHP_VERSION, '5.6.0', '<') ? 'CN_name' : 'peer_name';
7297
+ $http_array = array(
7298
+ 'method' => 'GET'
7299
+ );
7300
+ //configure fopen request for proxy
7301
+ if ( $proxy->is_enabled() && $proxy->send_through_proxy($url) ) {
7302
+ $http_array['proxy'] = 'tcp://'.$proxy->host().":".$proxy->port();
7303
+ if ( $proxy->use_authentication() )
7304
+ $http_array['header'] .= $proxy->authentication_header()."\r\n";
7305
+ }
7306
+ if ( $timeout > 0 ) $http_array['timeout'] = $timeout;
7307
+ //for internal requests to /wp-admin area that is password protected
7308
+ //authorization is required
7309
+ if ( $internal_request && WFU_VAR("WFU_DASHBOARD_PROTECTED") == "true" ) {
7310
+ $http_array['header'] .= "Authorization: Basic ".base64_encode(WFU_VAR("WFU_DASHBOARD_USERNAME").":".WFU_VAR("WFU_DASHBOARD_PASSWORD"))."\r\n";
7311
+ }
7312
+ $context_params = array( 'http' => $http_array );
7313
+ if ( !$verifypeer ) $context_params['ssl'] = array( 'verify_peer' => false, 'allow_self_signed' => true, 'verify_peer_name' => false );
7314
+ /** This filter is explained above. */
7315
+ $context_params = apply_filters("_wfu_get_request_options", $context_params, "fopen", $default_args);
7316
+ $context = stream_context_create($context_params);
7317
+ return file_get_contents($url, false, $context);
7318
+ }
7319
  }
lib/wfu_template.php CHANGED
@@ -178,6 +178,7 @@ button.wfu_overlay_editor_button, button.wfu_overlay_editor_button:focus {
178
  width: 100%;
179
  height: 100%;
180
  outline: none;
 
181
  }
182
 
183
  img.wfu_overlay_editor_img
@@ -2101,7 +2102,8 @@ this.updateStatus = function(status) {
2101
  var webcamoff = document.getElementById("webcam_$ID_webcamoff");
2102
  if (status == "idle") {
2103
  webcamoff.style.display = "none";
2104
- video.style.display = "block";
 
2105
  }
2106
  else if (status == "off") {
2107
  var img = document.getElementById("webcam_$ID_webcamoff_img");
@@ -2425,6 +2427,7 @@ this.screenshot = function(savefunc, image_type) {
2425
  */
2426
  this.play = function() {
2427
  var video = document.getElementById("webcam_$ID_box");
 
2428
  video.play();
2429
  }
2430
 
178
  width: 100%;
179
  height: 100%;
180
  outline: none;
181
+ display: block;
182
  }
183
 
184
  img.wfu_overlay_editor_img
2102
  var webcamoff = document.getElementById("webcam_$ID_webcamoff");
2103
  if (status == "idle") {
2104
  webcamoff.style.display = "none";
2105
+ video.style.display = "block";
2106
+ video.muted = true;
2107
  }
2108
  else if (status == "off") {
2109
  var img = document.getElementById("webcam_$ID_webcamoff_img");
2427
  */
2428
  this.play = function() {
2429
  var video = document.getElementById("webcam_$ID_box");
2430
+ video.muted = false;
2431
  video.play();
2432
  }
2433
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: nickboss
3
  Donate link: http://www.iptanus.com/support/wordpress-file-upload
4
  Tags: file, upload, ajax, form, page, post, sidebar, responsive, widget, webcam, ftp
5
  Requires at least: 2.9.2
6
- Tested up to: 5.7.1
7
  Stable tag: "trunk"
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -149,6 +149,10 @@ There is an option in plugin's settings in Dashboard to relax the CSS rules, so
149
 
150
  == Changelog ==
151
 
 
 
 
 
152
  = 4.15.0 =
153
  * COOKIEHASH bug corrected
154
  * credentials in FTP paths are stripped from the paths
@@ -899,6 +903,15 @@ Initial version.
899
 
900
  == Upgrade Notice ==
901
 
 
 
 
 
 
 
 
 
 
902
  = 4.14.3 =
903
  Regular update to fix some bugs and introduce some code improvements.
904
 
3
  Donate link: http://www.iptanus.com/support/wordpress-file-upload
4
  Tags: file, upload, ajax, form, page, post, sidebar, responsive, widget, webcam, ftp
5
  Requires at least: 2.9.2
6
+ Tested up to: 5.8.1
7
  Stable tag: "trunk"
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
149
 
150
  == Changelog ==
151
 
152
+ = 4.16.0 =
153
+ * visual editor edit button misalignment fixed
154
+ * corrected echo problem when recording from webcam with sound
155
+
156
  = 4.15.0 =
157
  * COOKIEHASH bug corrected
158
  * credentials in FTP paths are stripped from the paths
903
 
904
  == Upgrade Notice ==
905
 
906
+ = 4.16.0 =
907
+ Regular update to fix some bugs and introduce some code improvements.
908
+
909
+ = 4.15.0 =
910
+ Regular update to fix some bugs and introduce some code improvements.
911
+
912
+ = 4.14.4 =
913
+ Regular update to fix some bugs and introduce some code improvements.
914
+
915
  = 4.14.3 =
916
  Regular update to fix some bugs and introduce some code improvements.
917
 
release_notes.txt CHANGED
@@ -1,3 +1,3 @@
1
- <!-- --><span><strong>Version 4.15.0</strong> is a regular update that introduces some code improvements and bug fixes.<br /><br />
2
- For more details about this version's changes please visit the Release Notes of the plugin's </span><a href="http://www.iptanus.com/wordpress-plugins/wordpress-file-upload/">support page</a><span>.</span><!-- -->
3
  <!-- -->
1
+ <!-- --><span><strong>Version 4.16.0</strong> is a regular update that introduces some code improvements and bug fixes.<br /><br />
2
+ For more details about this version's changes please visit the <strong>Release Notes</strong> of the plugin's </span><a href="http://www.iptanus.com/wordpress-plugins/wordpress-file-upload/">support page</a><span>.</span><!-- -->
3
  <!-- -->
vendor/minifier/minify/LICENSE CHANGED
@@ -1,18 +1,18 @@
1
- Copyright (c) 2012 Matthias Mullie
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of
4
- this software and associated documentation files (the "Software"), to deal in
5
- the Software without restriction, including without limitation the rights to
6
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
- the Software, and to permit persons to whom the Software is furnished to do so,
8
- subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in all
11
- copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2012 Matthias Mullie
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
vendor/minifier/minify/data/js/keywords_after.txt CHANGED
@@ -1,7 +1,7 @@
1
- in
2
- public
3
- extends
4
- private
5
- protected
6
- implements
7
  instanceof
1
+ in
2
+ public
3
+ extends
4
+ private
5
+ protected
6
+ implements
7
  instanceof
vendor/minifier/minify/data/js/keywords_before.txt CHANGED
@@ -1,26 +1,26 @@
1
- do
2
- in
3
- let
4
- new
5
- var
6
- case
7
- else
8
- enum
9
- void
10
- with
11
- class
12
- const
13
- yield
14
- delete
15
- export
16
- import
17
- public
18
- static
19
- typeof
20
- extends
21
- package
22
- private
23
- function
24
- protected
25
- implements
26
  instanceof
1
+ do
2
+ in
3
+ let
4
+ new
5
+ var
6
+ case
7
+ else
8
+ enum
9
+ void
10
+ with
11
+ class
12
+ const
13
+ yield
14
+ delete
15
+ export
16
+ import
17
+ public
18
+ static
19
+ typeof
20
+ extends
21
+ package
22
+ private
23
+ function
24
+ protected
25
+ implements
26
  instanceof
vendor/minifier/minify/data/js/keywords_reserved.txt CHANGED
@@ -1,63 +1,63 @@
1
- do
2
- if
3
- in
4
- for
5
- let
6
- new
7
- try
8
- var
9
- case
10
- else
11
- enum
12
- eval
13
- null
14
- this
15
- true
16
- void
17
- with
18
- break
19
- catch
20
- class
21
- const
22
- false
23
- super
24
- throw
25
- while
26
- yield
27
- delete
28
- export
29
- import
30
- public
31
- return
32
- static
33
- switch
34
- typeof
35
- default
36
- extends
37
- finally
38
- package
39
- private
40
- continue
41
- debugger
42
- function
43
- arguments
44
- interface
45
- protected
46
- implements
47
- instanceof
48
- abstract
49
- boolean
50
- byte
51
- char
52
- double
53
- final
54
- float
55
- goto
56
- int
57
- long
58
- native
59
- short
60
- synchronized
61
- throws
62
- transient
63
  volatile
1
+ do
2
+ if
3
+ in
4
+ for
5
+ let
6
+ new
7
+ try
8
+ var
9
+ case
10
+ else
11
+ enum
12
+ eval
13
+ null
14
+ this
15
+ true
16
+ void
17
+ with
18
+ break
19
+ catch
20
+ class
21
+ const
22
+ false
23
+ super
24
+ throw
25
+ while
26
+ yield
27
+ delete
28
+ export
29
+ import
30
+ public
31
+ return
32
+ static
33
+ switch
34
+ typeof
35
+ default
36
+ extends
37
+ finally
38
+ package
39
+ private
40
+ continue
41
+ debugger
42
+ function
43
+ arguments
44
+ interface
45
+ protected
46
+ implements
47
+ instanceof
48
+ abstract
49
+ boolean
50
+ byte
51
+ char
52
+ double
53
+ final
54
+ float
55
+ goto
56
+ int
57
+ long
58
+ native
59
+ short
60
+ synchronized
61
+ throws
62
+ transient
63
  volatile
vendor/minifier/minify/data/js/operators.txt CHANGED
@@ -1,46 +1,46 @@
1
- +
2
- -
3
- *
4
- /
5
- %
6
- =
7
- +=
8
- -=
9
- *=
10
- /=
11
- %=
12
- <<=
13
- >>=
14
- >>>=
15
- &=
16
- ^=
17
- |=
18
- &
19
- |
20
- ^
21
- ~
22
- <<
23
- >>
24
- >>>
25
- ==
26
- ===
27
- !=
28
- !==
29
- >
30
- <
31
- >=
32
- <=
33
- &&
34
- ||
35
- !
36
- .
37
- [
38
- ]
39
- ?
40
- :
41
- ,
42
- ;
43
- (
44
- )
45
- {
46
  }
1
+ +
2
+ -
3
+ *
4
+ /
5
+ %
6
+ =
7
+ +=
8
+ -=
9
+ *=
10
+ /=
11
+ %=
12
+ <<=
13
+ >>=
14
+ >>>=
15
+ &=
16
+ ^=
17
+ |=
18
+ &
19
+ |
20
+ ^
21
+ ~
22
+ <<
23
+ >>
24
+ >>>
25
+ ==
26
+ ===
27
+ !=
28
+ !==
29
+ >
30
+ <
31
+ >=
32
+ <=
33
+ &&
34
+ ||
35
+ !
36
+ .
37
+ [
38
+ ]
39
+ ?
40
+ :
41
+ ,
42
+ ;
43
+ (
44
+ )
45
+ {
46
  }
vendor/minifier/minify/data/js/operators_after.txt CHANGED
@@ -1,43 +1,43 @@
1
- +
2
- -
3
- *
4
- /
5
- %
6
- =
7
- +=
8
- -=
9
- *=
10
- /=
11
- %=
12
- <<=
13
- >>=
14
- >>>=
15
- &=
16
- ^=
17
- |=
18
- &
19
- |
20
- ^
21
- <<
22
- >>
23
- >>>
24
- ==
25
- ===
26
- !=
27
- !==
28
- >
29
- <
30
- >=
31
- <=
32
- &&
33
- ||
34
- .
35
- [
36
- ]
37
- ?
38
- :
39
- ,
40
- ;
41
- (
42
- )
43
  }
1
+ +
2
+ -
3
+ *
4
+ /
5
+ %
6
+ =
7
+ +=
8
+ -=
9
+ *=
10
+ /=
11
+ %=
12
+ <<=
13
+ >>=
14
+ >>>=
15
+ &=
16
+ ^=
17
+ |=
18
+ &
19
+ |
20
+ ^
21
+ <<
22
+ >>
23
+ >>>
24
+ ==
25
+ ===
26
+ !=
27
+ !==
28
+ >
29
+ <
30
+ >=
31
+ <=
32
+ &&
33
+ ||
34
+ .
35
+ [
36
+ ]
37
+ ?
38
+ :
39
+ ,
40
+ ;
41
+ (
42
+ )
43
  }
vendor/minifier/minify/data/js/operators_before.txt CHANGED
@@ -1,43 +1,43 @@
1
- +
2
- -
3
- *
4
- /
5
- %
6
- =
7
- +=
8
- -=
9
- *=
10
- /=
11
- %=
12
- <<=
13
- >>=
14
- >>>=
15
- &=
16
- ^=
17
- |=
18
- &
19
- |
20
- ^
21
- ~
22
- <<
23
- >>
24
- >>>
25
- ==
26
- ===
27
- !=
28
- !==
29
- >
30
- <
31
- >=
32
- <=
33
- &&
34
- ||
35
- !
36
- .
37
- [
38
- ?
39
- :
40
- ,
41
- ;
42
- (
43
- {
1
+ +
2
+ -
3
+ *
4
+ /
5
+ %
6
+ =
7
+ +=
8
+ -=
9
+ *=
10
+ /=
11
+ %=
12
+ <<=
13
+ >>=
14
+ >>>=
15
+ &=
16
+ ^=
17
+ |=
18
+ &
19
+ |
20
+ ^
21
+ ~
22
+ <<
23
+ >>
24
+ >>>
25
+ ==
26
+ ===
27
+ !=
28
+ !==
29
+ >
30
+ <
31
+ >=
32
+ <=
33
+ &&
34
+ ||
35
+ !
36
+ .
37
+ [
38
+ ?
39
+ :
40
+ ,
41
+ ;
42
+ (
43
+ {
vendor/minifier/minify/src/CSS.php CHANGED
@@ -1,752 +1,786 @@
1
- <?php
2
- /**
3
- * CSS Minifier
4
- *
5
- * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
- *
7
- * @author Matthias Mullie <minify@mullie.eu>
8
- * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
- * @license MIT License
10
- */
11
-
12
- namespace MatthiasMullie\Minify;
13
-
14
- use MatthiasMullie\Minify\Exceptions\FileImportException;
15
- use MatthiasMullie\PathConverter\ConverterInterface;
16
- use MatthiasMullie\PathConverter\Converter;
17
-
18
- /**
19
- * CSS minifier
20
- *
21
- * Please report bugs on https://github.com/matthiasmullie/minify/issues
22
- *
23
- * @package Minify
24
- * @author Matthias Mullie <minify@mullie.eu>
25
- * @author Tijs Verkoyen <minify@verkoyen.eu>
26
- * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
27
- * @license MIT License
28
- */
29
- class CSS extends Minify
30
- {
31
- /**
32
- * @var int maximum inport size in kB
33
- */
34
- protected $maxImportSize = 5;
35
-
36
- /**
37
- * @var string[] valid import extensions
38
- */
39
- protected $importExtensions = array(
40
- 'gif' => 'data:image/gif',
41
- 'png' => 'data:image/png',
42
- 'jpe' => 'data:image/jpeg',
43
- 'jpg' => 'data:image/jpeg',
44
- 'jpeg' => 'data:image/jpeg',
45
- 'svg' => 'data:image/svg+xml',
46
- 'woff' => 'data:application/x-font-woff',
47
- 'tif' => 'image/tiff',
48
- 'tiff' => 'image/tiff',
49
- 'xbm' => 'image/x-xbitmap',
50
- );
51
-
52
- /**
53
- * Set the maximum size if files to be imported.
54
- *
55
- * Files larger than this size (in kB) will not be imported into the CSS.
56
- * Importing files into the CSS as data-uri will save you some connections,
57
- * but we should only import relatively small decorative images so that our
58
- * CSS file doesn't get too bulky.
59
- *
60
- * @param int $size Size in kB
61
- */
62
- public function setMaxImportSize($size)
63
- {
64
- $this->maxImportSize = $size;
65
- }
66
-
67
- /**
68
- * Set the type of extensions to be imported into the CSS (to save network
69
- * connections).
70
- * Keys of the array should be the file extensions & respective values
71
- * should be the data type.
72
- *
73
- * @param string[] $extensions Array of file extensions
74
- */
75
- public function setImportExtensions(array $extensions)
76
- {
77
- $this->importExtensions = $extensions;
78
- }
79
-
80
- /**
81
- * Move any import statements to the top.
82
- *
83
- * @param string $content Nearly finished CSS content
84
- *
85
- * @return string
86
- */
87
- protected function moveImportsToTop($content)
88
- {
89
- if (preg_match_all('/(;?)(@import (?<url>url\()?(?P<quotes>["\']?).+?(?P=quotes)(?(url)\)));?/', $content, $matches)) {
90
- // remove from content
91
- foreach ($matches[0] as $import) {
92
- $content = str_replace($import, '', $content);
93
- }
94
-
95
- // add to top
96
- $content = implode(';', $matches[2]).';'.trim($content, ';');
97
- }
98
-
99
- return $content;
100
- }
101
-
102
- /**
103
- * Combine CSS from import statements.
104
- *
105
- * @import's will be loaded and their content merged into the original file,
106
- * to save HTTP requests.
107
- *
108
- * @param string $source The file to combine imports for
109
- * @param string $content The CSS content to combine imports for
110
- * @param string[] $parents Parent paths, for circular reference checks
111
- *
112
- * @return string
113
- *
114
- * @throws FileImportException
115
- */
116
- protected function combineImports($source, $content, $parents)
117
- {
118
- $importRegexes = array(
119
- // @import url(xxx)
120
- '/
121
- # import statement
122
- @import
123
-
124
- # whitespace
125
- \s+
126
-
127
- # open url()
128
- url\(
129
-
130
- # (optional) open path enclosure
131
- (?P<quotes>["\']?)
132
-
133
- # fetch path
134
- (?P<path>.+?)
135
-
136
- # (optional) close path enclosure
137
- (?P=quotes)
138
-
139
- # close url()
140
- \)
141
-
142
- # (optional) trailing whitespace
143
- \s*
144
-
145
- # (optional) media statement(s)
146
- (?P<media>[^;]*)
147
-
148
- # (optional) trailing whitespace
149
- \s*
150
-
151
- # (optional) closing semi-colon
152
- ;?
153
-
154
- /ix',
155
-
156
- // @import 'xxx'
157
- '/
158
-
159
- # import statement
160
- @import
161
-
162
- # whitespace
163
- \s+
164
-
165
- # open path enclosure
166
- (?P<quotes>["\'])
167
-
168
- # fetch path
169
- (?P<path>.+?)
170
-
171
- # close path enclosure
172
- (?P=quotes)
173
-
174
- # (optional) trailing whitespace
175
- \s*
176
-
177
- # (optional) media statement(s)
178
- (?P<media>[^;]*)
179
-
180
- # (optional) trailing whitespace
181
- \s*
182
-
183
- # (optional) closing semi-colon
184
- ;?
185
-
186
- /ix',
187
- );
188
-
189
- // find all relative imports in css
190
- $matches = array();
191
- foreach ($importRegexes as $importRegex) {
192
- if (preg_match_all($importRegex, $content, $regexMatches, PREG_SET_ORDER)) {
193
- $matches = array_merge($matches, $regexMatches);
194
- }
195
- }
196
-
197
- $search = array();
198
- $replace = array();
199
-
200
- // loop the matches
201
- foreach ($matches as $match) {
202
- // get the path for the file that will be imported
203
- $importPath = dirname($source).'/'.$match['path'];
204
-
205
- // only replace the import with the content if we can grab the
206
- // content of the file
207
- if (!$this->canImportByPath($match['path']) || !$this->canImportFile($importPath)) {
208
- continue;
209
- }
210
-
211
- // check if current file was not imported previously in the same
212
- // import chain.
213
- if (in_array($importPath, $parents)) {
214
- throw new FileImportException('Failed to import file "'.$importPath.'": circular reference detected.');
215
- }
216
-
217
- // grab referenced file & minify it (which may include importing
218
- // yet other @import statements recursively)
219
- $minifier = new static($importPath);
220
- $minifier->setMaxImportSize($this->maxImportSize);
221
- $minifier->setImportExtensions($this->importExtensions);
222
- $importContent = $minifier->execute($source, $parents);
223
-
224
- // check if this is only valid for certain media
225
- if (!empty($match['media'])) {
226
- $importContent = '@media '.$match['media'].'{'.$importContent.'}';
227
- }
228
-
229
- // add to replacement array
230
- $search[] = $match[0];
231
- $replace[] = $importContent;
232
- }
233
-
234
- // replace the import statements
235
- return str_replace($search, $replace, $content);
236
- }
237
-
238
- /**
239
- * Import files into the CSS, base64-ized.
240
- *
241
- * @url(image.jpg) images will be loaded and their content merged into the
242
- * original file, to save HTTP requests.
243
- *
244
- * @param string $source The file to import files for
245
- * @param string $content The CSS content to import files for
246
- *
247
- * @return string
248
- */
249
- protected function importFiles($source, $content)
250
- {
251
- $regex = '/url\((["\']?)(.+?)\\1\)/i';
252
- if ($this->importExtensions && preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {
253
- $search = array();
254
- $replace = array();
255
-
256
- // loop the matches
257
- foreach ($matches as $match) {
258
- $extension = substr(strrchr($match[2], '.'), 1);
259
- if ($extension && !array_key_exists($extension, $this->importExtensions)) {
260
- continue;
261
- }
262
-
263
- // get the path for the file that will be imported
264
- $path = $match[2];
265
- $path = dirname($source).'/'.$path;
266
-
267
- // only replace the import with the content if we're able to get
268
- // the content of the file, and it's relatively small
269
- if ($this->canImportFile($path) && $this->canImportBySize($path)) {
270
- // grab content && base64-ize
271
- $importContent = $this->load($path);
272
- $importContent = base64_encode($importContent);
273
-
274
- // build replacement
275
- $search[] = $match[0];
276
- $replace[] = 'url('.$this->importExtensions[$extension].';base64,'.$importContent.')';
277
- }
278
- }
279
-
280
- // replace the import statements
281
- $content = str_replace($search, $replace, $content);
282
- }
283
-
284
- return $content;
285
- }
286
-
287
- /**
288
- * Minify the data.
289
- * Perform CSS optimizations.
290
- *
291
- * @param string[optional] $path Path to write the data to
292
- * @param string[] $parents Parent paths, for circular reference checks
293
- *
294
- * @return string The minified data
295
- */
296
- public function execute($path = null, $parents = array())
297
- {
298
- $content = '';
299
-
300
- // loop CSS data (raw data and files)
301
- foreach ($this->data as $source => $css) {
302
- /*
303
- * Let's first take out strings & comments, since we can't just
304
- * remove whitespace anywhere. If whitespace occurs inside a string,
305
- * we should leave it alone. E.g.:
306
- * p { content: "a test" }
307
- */
308
- $this->extractStrings();
309
- $this->stripComments();
310
- $this->extractCalcs();
311
- $css = $this->replace($css);
312
-
313
- $css = $this->stripWhitespace($css);
314
- $css = $this->shortenColors($css);
315
- $css = $this->shortenZeroes($css);
316
- $css = $this->shortenFontWeights($css);
317
- $css = $this->stripEmptyTags($css);
318
-
319
- // restore the string we've extracted earlier
320
- $css = $this->restoreExtractedData($css);
321
-
322
- $source = is_int($source) ? '' : $source;
323
- $parents = $source ? array_merge($parents, array($source)) : $parents;
324
- $css = $this->combineImports($source, $css, $parents);
325
- $css = $this->importFiles($source, $css);
326
-
327
- /*
328
- * If we'll save to a new path, we'll have to fix the relative paths
329
- * to be relative no longer to the source file, but to the new path.
330
- * If we don't write to a file, fall back to same path so no
331
- * conversion happens (because we still want it to go through most
332
- * of the move code, which also addresses url() & @import syntax...)
333
- */
334
- $converter = $this->getPathConverter($source, $path ?: $source);
335
- $css = $this->move($converter, $css);
336
-
337
- // combine css
338
- $content .= $css;
339
- }
340
-
341
- $content = $this->moveImportsToTop($content);
342
-
343
- return $content;
344
- }
345
-
346
- /**
347
- * Moving a css file should update all relative urls.
348
- * Relative references (e.g. ../images/image.gif) in a certain css file,
349
- * will have to be updated when a file is being saved at another location
350
- * (e.g. ../../images/image.gif, if the new CSS file is 1 folder deeper).
351
- *
352
- * @param ConverterInterface $converter Relative path converter
353
- * @param string $content The CSS content to update relative urls for
354
- *
355
- * @return string
356
- */
357
- protected function move(ConverterInterface $converter, $content)
358
- {
359
- /*
360
- * Relative path references will usually be enclosed by url(). @import
361
- * is an exception, where url() is not necessary around the path (but is
362
- * allowed).
363
- * This *could* be 1 regular expression, where both regular expressions
364
- * in this array are on different sides of a |. But we're using named
365
- * patterns in both regexes, the same name on both regexes. This is only
366
- * possible with a (?J) modifier, but that only works after a fairly
367
- * recent PCRE version. That's why I'm doing 2 separate regular
368
- * expressions & combining the matches after executing of both.
369
- */
370
- $relativeRegexes = array(
371
- // url(xxx)
372
- '/
373
- # open url()
374
- url\(
375
-
376
- \s*
377
-
378
- # open path enclosure
379
- (?P<quotes>["\'])?
380
-
381
- # fetch path
382
- (?P<path>.+?)
383
-
384
- # close path enclosure
385
- (?(quotes)(?P=quotes))
386
-
387
- \s*
388
-
389
- # close url()
390
- \)
391
-
392
- /ix',
393
-
394
- // @import "xxx"
395
- '/
396
- # import statement
397
- @import
398
-
399
- # whitespace
400
- \s+
401
-
402
- # we don\'t have to check for @import url(), because the
403
- # condition above will already catch these
404
-
405
- # open path enclosure
406
- (?P<quotes>["\'])
407
-
408
- # fetch path
409
- (?P<path>.+?)
410
-
411
- # close path enclosure
412
- (?P=quotes)
413
-
414
- /ix',
415
- );
416
-
417
- // find all relative urls in css
418
- $matches = array();
419
- foreach ($relativeRegexes as $relativeRegex) {
420
- if (preg_match_all($relativeRegex, $content, $regexMatches, PREG_SET_ORDER)) {
421
- $matches = array_merge($matches, $regexMatches);
422
- }
423
- }
424
-
425
- $search = array();
426
- $replace = array();
427
-
428
- // loop all urls
429
- foreach ($matches as $match) {
430
- // determine if it's a url() or an @import match
431
- $type = (strpos($match[0], '@import') === 0 ? 'import' : 'url');
432
-
433
- $url = $match['path'];
434
- if ($this->canImportByPath($url)) {
435
- // attempting to interpret GET-params makes no sense, so let's discard them for awhile
436
- $params = strrchr($url, '?');
437
- $url = $params ? substr($url, 0, -strlen($params)) : $url;
438
-
439
- // fix relative url
440
- $url = $converter->convert($url);
441
-
442
- // now that the path has been converted, re-apply GET-params
443
- $url .= $params;
444
- }
445
-
446
- /*
447
- * Urls with control characters above 0x7e should be quoted.
448
- * According to Mozilla's parser, whitespace is only allowed at the
449
- * end of unquoted urls.
450
- * Urls with `)` (as could happen with data: uris) should also be
451
- * quoted to avoid being confused for the url() closing parentheses.
452
- * And urls with a # have also been reported to cause issues.
453
- * Urls with quotes inside should also remain escaped.
454
- *
455
- * @see https://developer.mozilla.org/nl/docs/Web/CSS/url#The_url()_functional_notation
456
- * @see https://hg.mozilla.org/mozilla-central/rev/14abca4e7378
457
- * @see https://github.com/matthiasmullie/minify/issues/193
458
- */
459
- $url = trim($url);
460
- if (preg_match('/[\s\)\'"#\x{7f}-\x{9f}]/u', $url)) {
461
- $url = $match['quotes'] . $url . $match['quotes'];
462
- }
463
-
464
- // build replacement
465
- $search[] = $match[0];
466
- if ($type === 'url') {
467
- $replace[] = 'url('.$url.')';
468
- } elseif ($type === 'import') {
469
- $replace[] = '@import "'.$url.'"';
470
- }
471
- }
472
-
473
- // replace urls
474
- return str_replace($search, $replace, $content);
475
- }
476
-
477
- /**
478
- * Shorthand hex color codes.
479
- * #FF0000 -> #F00.
480
- *
481
- * @param string $content The CSS content to shorten the hex color codes for
482
- *
483
- * @return string
484
- */
485
- protected function shortenColors($content)
486
- {
487
- $content = preg_replace('/(?<=[: ])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?:([0-9a-z])\\4)?(?=[; }])/i', '#$1$2$3$4', $content);
488
-
489
- // remove alpha channel if it's pointless...
490
- $content = preg_replace('/(?<=[: ])#([0-9a-z]{6})ff?(?=[; }])/i', '#$1', $content);
491
- $content = preg_replace('/(?<=[: ])#([0-9a-z]{3})f?(?=[; }])/i', '#$1', $content);
492
-
493
- $colors = array(
494
- // we can shorten some even more by replacing them with their color name
495
- '#F0FFFF' => 'azure',
496
- '#F5F5DC' => 'beige',
497
- '#A52A2A' => 'brown',
498
- '#FF7F50' => 'coral',
499
- '#FFD700' => 'gold',
500
- '#808080' => 'gray',
501
- '#008000' => 'green',
502
- '#4B0082' => 'indigo',
503
- '#FFFFF0' => 'ivory',
504
- '#F0E68C' => 'khaki',
505
- '#FAF0E6' => 'linen',
506
- '#800000' => 'maroon',
507
- '#000080' => 'navy',
508
- '#808000' => 'olive',
509
- '#CD853F' => 'peru',
510
- '#FFC0CB' => 'pink',
511
- '#DDA0DD' => 'plum',
512
- '#800080' => 'purple',
513
- '#F00' => 'red',
514
- '#FA8072' => 'salmon',
515
- '#A0522D' => 'sienna',
516
- '#C0C0C0' => 'silver',
517
- '#FFFAFA' => 'snow',
518
- '#D2B48C' => 'tan',
519
- '#FF6347' => 'tomato',
520
- '#EE82EE' => 'violet',
521
- '#F5DEB3' => 'wheat',
522
- // or the other way around
523
- 'WHITE' => '#fff',
524
- 'BLACK' => '#000',
525
- );
526
-
527
- return preg_replace_callback(
528
- '/(?<=[: ])('.implode('|', array_keys($colors)).')(?=[; }])/i',
529
- function ($match) use ($colors) {
530
- return $colors[strtoupper($match[0])];
531
- },
532
- $content
533
- );
534
- }
535
-
536
- /**
537
- * Shorten CSS font weights.
538
- *
539
- * @param string $content The CSS content to shorten the font weights for
540
- *
541
- * @return string
542
- */
543
- protected function shortenFontWeights($content)
544
- {
545
- $weights = array(
546
- 'normal' => 400,
547
- 'bold' => 700,
548
- );
549
-
550
- $callback = function ($match) use ($weights) {
551
- return $match[1].$weights[$match[2]];
552
- };
553
-
554
- return preg_replace_callback('/(font-weight\s*:\s*)('.implode('|', array_keys($weights)).')(?=[;}])/', $callback, $content);
555
- }
556
-
557
- /**
558
- * Shorthand 0 values to plain 0, instead of e.g. -0em.
559
- *
560
- * @param string $content The CSS content to shorten the zero values for
561
- *
562
- * @return string
563
- */
564
- protected function shortenZeroes($content)
565
- {
566
- // we don't want to strip units in `calc()` expressions:
567
- // `5px - 0px` is valid, but `5px - 0` is not
568
- // `10px * 0` is valid (equates to 0), and so is `10 * 0px`, but
569
- // `10 * 0` is invalid
570
- // we've extracted calcs earlier, so we don't need to worry about this
571
-
572
- // reusable bits of code throughout these regexes:
573
- // before & after are used to make sure we don't match lose unintended
574
- // 0-like values (e.g. in #000, or in http://url/1.0)
575
- // units can be stripped from 0 values, or used to recognize non 0
576
- // values (where wa may be able to strip a .0 suffix)
577
- $before = '(?<=[:(, ])';
578
- $after = '(?=[ ,);}])';
579
- $units = '(em|ex|%|px|cm|mm|in|pt|pc|ch|rem|vh|vw|vmin|vmax|vm)';
580
-
581
- // strip units after zeroes (0px -> 0)
582
- // NOTE: it should be safe to remove all units for a 0 value, but in
583
- // practice, Webkit (especially Safari) seems to stumble over at least
584
- // 0%, potentially other units as well. Only stripping 'px' for now.
585
- // @see https://github.com/matthiasmullie/minify/issues/60
586
- $content = preg_replace('/'.$before.'(-?0*(\.0+)?)(?<=0)px'.$after.'/', '\\1', $content);
587
-
588
- // strip 0-digits (.0 -> 0)
589
- $content = preg_replace('/'.$before.'\.0+'.$units.'?'.$after.'/', '0\\1', $content);
590
- // strip trailing 0: 50.10 -> 50.1, 50.10px -> 50.1px
591
- $content = preg_replace('/'.$before.'(-?[0-9]+\.[0-9]+)0+'.$units.'?'.$after.'/', '\\1\\2', $content);
592
- // strip trailing 0: 50.00 -> 50, 50.00px -> 50px
593
- $content = preg_replace('/'.$before.'(-?[0-9]+)\.0+'.$units.'?'.$after.'/', '\\1\\2', $content);
594
- // strip leading 0: 0.1 -> .1, 01.1 -> 1.1
595
- $content = preg_replace('/'.$before.'(-?)0+([0-9]*\.[0-9]+)'.$units.'?'.$after.'/', '\\1\\2\\3', $content);
596
-
597
- // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
598
- $content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
599
-
600
- // IE doesn't seem to understand a unitless flex-basis value (correct -
601
- // it goes against the spec), so let's add it in again (make it `%`,
602
- // which is only 1 char: 0%, 0px, 0 anything, it's all just the same)
603
- // @see https://developer.mozilla.org/nl/docs/Web/CSS/flex
604
- $content = preg_replace('/flex:([0-9]+\s[0-9]+\s)0([;\}])/', 'flex:${1}0%${2}', $content);
605
- $content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
606
-
607
- return $content;
608
- }
609
-
610
- /**
611
- * Strip empty tags from source code.
612
- *
613
- * @param string $content
614
- *
615
- * @return string
616
- */
617
- protected function stripEmptyTags($content)
618
- {
619
- $content = preg_replace('/(?<=^)[^\{\};]+\{\s*\}/', '', $content);
620
- $content = preg_replace('/(?<=(\}|;))[^\{\};]+\{\s*\}/', '', $content);
621
-
622
- return $content;
623
- }
624
-
625
- /**
626
- * Strip comments from source code.
627
- */
628
- protected function stripComments()
629
- {
630
- // PHP only supports $this inside anonymous functions since 5.4
631
- $minifier = $this;
632
- $callback = function ($match) use ($minifier) {
633
- $count = count($minifier->extracted);
634
- $placeholder = '/*'.$count.'*/';
635
- $minifier->extracted[$placeholder] = $match[0];
636
-
637
- return $placeholder;
638
- };
639
- $this->registerPattern('/\n?\/\*(!|.*?@license|.*?@preserve).*?\*\/\n?/s', $callback);
640
-
641
- $this->registerPattern('/\/\*.*?\*\//s', '');
642
- }
643
-
644
- /**
645
- * Strip whitespace.
646
- *
647
- * @param string $content The CSS content to strip the whitespace for
648
- *
649
- * @return string
650
- */
651
- protected function stripWhitespace($content)
652
- {
653
- // remove leading & trailing whitespace
654
- $content = preg_replace('/^\s*/m', '', $content);
655
- $content = preg_replace('/\s*$/m', '', $content);
656
-
657
- // replace newlines with a single space
658
- $content = preg_replace('/\s+/', ' ', $content);
659
-
660
- // remove whitespace around meta characters
661
- // inspired by stackoverflow.com/questions/15195750/minify-compress-css-with-regex
662
- $content = preg_replace('/\s*([\*$~^|]?+=|[{};,>~]|!important\b)\s*/', '$1', $content);
663
- $content = preg_replace('/([\[(:>\+])\s+/', '$1', $content);
664
- $content = preg_replace('/\s+([\]\)>\+])/', '$1', $content);
665
- $content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
666
-
667
- // whitespace around + and - can only be stripped inside some pseudo-
668
- // classes, like `:nth-child(3+2n)`
669
- // not in things like `calc(3px + 2px)`, shorthands like `3px -2px`, or
670
- // selectors like `div.weird- p`
671
- $pseudos = array('nth-child', 'nth-last-child', 'nth-last-of-type', 'nth-of-type');
672
- $content = preg_replace('/:('.implode('|', $pseudos).')\(\s*([+-]?)\s*(.+?)\s*([+-]?)\s*(.*?)\s*\)/', ':$1($2$3$4$5)', $content);
673
-
674
- // remove semicolon/whitespace followed by closing bracket
675
- $content = str_replace(';}', '}', $content);
676
-
677
- return trim($content);
678
- }
679
-
680
- /**
681
- * Replace all `calc()` occurrences.
682
- */
683
- protected function extractCalcs()
684
- {
685
- // PHP only supports $this inside anonymous functions since 5.4
686
- $minifier = $this;
687
- $callback = function ($match) use ($minifier) {
688
- $length = strlen($match[1]);
689
- $expr = '';
690
- $opened = 0;
691
-
692
- for ($i = 0; $i < $length; $i++) {
693
- $char = $match[1][$i];
694
- $expr .= $char;
695
- if ($char === '(') {
696
- $opened++;
697
- } elseif ($char === ')' && --$opened === 0) {
698
- break;
699
- }
700
- }
701
- $rest = str_replace($expr, '', $match[1]);
702
- $expr = trim(substr($expr, 1, -1));
703
-
704
- $count = count($minifier->extracted);
705
- $placeholder = 'calc('.$count.')';
706
- $minifier->extracted[$placeholder] = 'calc('.$expr.')';
707
-
708
- return $placeholder.$rest;
709
- };
710
-
711
- $this->registerPattern('/calc(\(.+?)(?=$|;|}|calc\()/', $callback);
712
- $this->registerPattern('/calc(\(.+?)(?=$|;|}|calc\()/m', $callback);
713
- }
714
-
715
- /**
716
- * Check if file is small enough to be imported.
717
- *
718
- * @param string $path The path to the file
719
- *
720
- * @return bool
721
- */
722
- protected function canImportBySize($path)
723
- {
724
- return ($size = @filesize($path)) && $size <= $this->maxImportSize * 1024;
725
- }
726
-
727
- /**
728
- * Check if file a file can be imported, going by the path.
729
- *
730
- * @param string $path
731
- *
732
- * @return bool
733
- */
734
- protected function canImportByPath($path)
735
- {
736
- return preg_match('/^(data:|https?:|\\/)/', $path) === 0;
737
- }
738
-
739
- /**
740
- * Return a converter to update relative paths to be relative to the new
741
- * destination.
742
- *
743
- * @param string $source
744
- * @param string $target
745
- *
746
- * @return ConverterInterface
747
- */
748
- protected function getPathConverter($source, $target)
749
- {
750
- return new Converter($source, $target);
751
- }
752
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CSS Minifier
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
+
12
+ namespace MatthiasMullie\Minify;
13
+
14
+ use MatthiasMullie\Minify\Exceptions\FileImportException;
15
+ use MatthiasMullie\PathConverter\ConverterInterface;
16
+ use MatthiasMullie\PathConverter\Converter;
17
+
18
+ /**
19
+ * CSS minifier
20
+ *
21
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
22
+ *
23
+ * @package Minify
24
+ * @author Matthias Mullie <minify@mullie.eu>
25
+ * @author Tijs Verkoyen <minify@verkoyen.eu>
26
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
27
+ * @license MIT License
28
+ */
29
+ class CSS extends Minify
30
+ {
31
+ /**
32
+ * @var int maximum inport size in kB
33
+ */
34
+ protected $maxImportSize = 5;
35
+
36
+ /**
37
+ * @var string[] valid import extensions
38
+ */
39
+ protected $importExtensions = array(
40
+ 'gif' => 'data:image/gif',
41
+ 'png' => 'data:image/png',
42
+ 'jpe' => 'data:image/jpeg',
43
+ 'jpg' => 'data:image/jpeg',
44
+ 'jpeg' => 'data:image/jpeg',
45
+ 'svg' => 'data:image/svg+xml',
46
+ 'woff' => 'data:application/x-font-woff',
47
+ 'tif' => 'image/tiff',
48
+ 'tiff' => 'image/tiff',
49
+ 'xbm' => 'image/x-xbitmap',
50
+ );
51
+
52
+ /**
53
+ * Set the maximum size if files to be imported.
54
+ *
55
+ * Files larger than this size (in kB) will not be imported into the CSS.
56
+ * Importing files into the CSS as data-uri will save you some connections,
57
+ * but we should only import relatively small decorative images so that our
58
+ * CSS file doesn't get too bulky.
59
+ *
60
+ * @param int $size Size in kB
61
+ */
62
+ public function setMaxImportSize($size)
63
+ {
64
+ $this->maxImportSize = $size;
65
+ }
66
+
67
+ /**
68
+ * Set the type of extensions to be imported into the CSS (to save network
69
+ * connections).
70
+ * Keys of the array should be the file extensions & respective values
71
+ * should be the data type.
72
+ *
73
+ * @param string[] $extensions Array of file extensions
74
+ */
75
+ public function setImportExtensions(array $extensions)
76
+ {
77
+ $this->importExtensions = $extensions;
78
+ }
79
+
80
+ /**
81
+ * Move any import statements to the top.
82
+ *
83
+ * @param string $content Nearly finished CSS content
84
+ *
85
+ * @return string
86
+ */
87
+ protected function moveImportsToTop($content)
88
+ {
89
+ if (preg_match_all('/(;?)(@import (?<url>url\()?(?P<quotes>["\']?).+?(?P=quotes)(?(url)\)));?/', $content, $matches)) {
90
+ // remove from content
91
+ foreach ($matches[0] as $import) {
92
+ $content = str_replace($import, '', $content);
93
+ }
94
+
95
+ // add to top
96
+ $content = implode(';', $matches[2]).';'.trim($content, ';');
97
+ }
98
+
99
+ return $content;
100
+ }
101
+
102
+ /**
103
+ * Combine CSS from import statements.
104
+ *
105
+ * @import's will be loaded and their content merged into the original file,
106
+ * to save HTTP requests.
107
+ *
108
+ * @param string $source The file to combine imports for
109
+ * @param string $content The CSS content to combine imports for
110
+ * @param string[] $parents Parent paths, for circular reference checks
111
+ *
112
+ * @return string
113
+ *
114
+ * @throws FileImportException
115
+ */
116
+ protected function combineImports($source, $content, $parents)
117
+ {
118
+ $importRegexes = array(
119
+ // @import url(xxx)
120
+ '/
121
+ # import statement
122
+ @import
123
+
124
+ # whitespace
125
+ \s+
126
+
127
+ # open url()
128
+ url\(
129
+
130
+ # (optional) open path enclosure
131
+ (?P<quotes>["\']?)
132
+
133
+ # fetch path
134
+ (?P<path>.+?)
135
+
136
+ # (optional) close path enclosure
137
+ (?P=quotes)
138
+
139
+ # close url()
140
+ \)
141
+
142
+ # (optional) trailing whitespace
143
+ \s*
144
+
145
+ # (optional) media statement(s)
146
+ (?P<media>[^;]*)
147
+
148
+ # (optional) trailing whitespace
149
+ \s*
150
+
151
+ # (optional) closing semi-colon
152
+ ;?
153
+
154
+ /ix',
155
+
156
+ // @import 'xxx'
157
+ '/
158
+
159
+ # import statement
160
+ @import
161
+
162
+ # whitespace
163
+ \s+
164
+
165
+ # open path enclosure
166
+ (?P<quotes>["\'])
167
+
168
+ # fetch path
169
+ (?P<path>.+?)
170
+
171
+ # close path enclosure
172
+ (?P=quotes)
173
+
174
+ # (optional) trailing whitespace
175
+ \s*
176
+
177
+ # (optional) media statement(s)
178
+ (?P<media>[^;]*)
179
+
180
+ # (optional) trailing whitespace
181
+ \s*
182
+
183
+ # (optional) closing semi-colon
184
+ ;?
185
+
186
+ /ix',
187
+ );
188
+
189
+ // find all relative imports in css
190
+ $matches = array();
191
+ foreach ($importRegexes as $importRegex) {
192
+ if (preg_match_all($importRegex, $content, $regexMatches, PREG_SET_ORDER)) {
193
+ $matches = array_merge($matches, $regexMatches);
194
+ }
195
+ }
196
+
197
+ $search = array();
198
+ $replace = array();
199
+
200
+ // loop the matches
201
+ foreach ($matches as $match) {
202
+ // get the path for the file that will be imported
203
+ $importPath = dirname($source).'/'.$match['path'];
204
+
205
+ // only replace the import with the content if we can grab the
206
+ // content of the file
207
+ if (!$this->canImportByPath($match['path']) || !$this->canImportFile($importPath)) {
208
+ continue;
209
+ }
210
+
211
+ // check if current file was not imported previously in the same
212
+ // import chain.
213
+ if (in_array($importPath, $parents)) {
214
+ throw new FileImportException('Failed to import file "'.$importPath.'": circular reference detected.');
215
+ }
216
+
217
+ // grab referenced file & minify it (which may include importing
218
+ // yet other @import statements recursively)
219
+ $minifier = new self($importPath);
220
+ $minifier->setMaxImportSize($this->maxImportSize);
221
+ $minifier->setImportExtensions($this->importExtensions);
222
+ $importContent = $minifier->execute($source, $parents);
223
+
224
+ // check if this is only valid for certain media
225
+ if (!empty($match['media'])) {
226
+ $importContent = '@media '.$match['media'].'{'.$importContent.'}';
227
+ }
228
+
229
+ // add to replacement array
230
+ $search[] = $match[0];
231
+ $replace[] = $importContent;
232
+ }
233
+
234
+ // replace the import statements
235
+ return str_replace($search, $replace, $content);
236
+ }
237
+
238
+ /**
239
+ * Import files into the CSS, base64-ized.
240
+ *
241
+ * @url(image.jpg) images will be loaded and their content merged into the
242
+ * original file, to save HTTP requests.
243
+ *
244
+ * @param string $source The file to import files for
245
+ * @param string $content The CSS content to import files for
246
+ *
247
+ * @return string
248
+ */
249
+ protected function importFiles($source, $content)
250
+ {
251
+ $regex = '/url\((["\']?)(.+?)\\1\)/i';
252
+ if ($this->importExtensions && preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {
253
+ $search = array();
254
+ $replace = array();
255
+
256
+ // loop the matches
257
+ foreach ($matches as $match) {
258
+ $extension = substr(strrchr($match[2], '.'), 1);
259
+ if ($extension && !array_key_exists($extension, $this->importExtensions)) {
260
+ continue;
261
+ }
262
+
263
+ // get the path for the file that will be imported
264
+ $path = $match[2];
265
+ $path = dirname($source).'/'.$path;
266
+
267
+ // only replace the import with the content if we're able to get
268
+ // the content of the file, and it's relatively small
269
+ if ($this->canImportFile($path) && $this->canImportBySize($path)) {
270
+ // grab content && base64-ize
271
+ $importContent = $this->load($path);
272
+ $importContent = base64_encode($importContent);
273
+
274
+ // build replacement
275
+ $search[] = $match[0];
276
+ $replace[] = 'url('.$this->importExtensions[$extension].';base64,'.$importContent.')';
277
+ }
278
+ }
279
+
280
+ // replace the import statements
281
+ $content = str_replace($search, $replace, $content);
282
+ }
283
+
284
+ return $content;
285
+ }
286
+
287
+ /**
288
+ * Minify the data.
289
+ * Perform CSS optimizations.
290
+ *
291
+ * @param string[optional] $path Path to write the data to
292
+ * @param string[] $parents Parent paths, for circular reference checks
293
+ *
294
+ * @return string The minified data
295
+ */
296
+ public function execute($path = null, $parents = array())
297
+ {
298
+ $content = '';
299
+
300
+ // loop CSS data (raw data and files)
301
+ foreach ($this->data as $source => $css) {
302
+ /*
303
+ * Let's first take out strings & comments, since we can't just
304
+ * remove whitespace anywhere. If whitespace occurs inside a string,
305
+ * we should leave it alone. E.g.:
306
+ * p { content: "a test" }
307
+ */
308
+ $this->extractStrings();
309
+ $this->stripComments();
310
+ $this->extractMath();
311
+ $this->extractCustomProperties();
312
+ $css = $this->replace($css);
313
+
314
+ $css = $this->stripWhitespace($css);
315
+ $css = $this->shortenColors($css);
316
+ $css = $this->shortenZeroes($css);
317
+ $css = $this->shortenFontWeights($css);
318
+ $css = $this->stripEmptyTags($css);
319
+
320
+ // restore the string we've extracted earlier
321
+ $css = $this->restoreExtractedData($css);
322
+
323
+ $source = is_int($source) ? '' : $source;
324
+ $parents = $source ? array_merge($parents, array($source)) : $parents;
325
+ $css = $this->combineImports($source, $css, $parents);
326
+ $css = $this->importFiles($source, $css);
327
+
328
+ /*
329
+ * If we'll save to a new path, we'll have to fix the relative paths
330
+ * to be relative no longer to the source file, but to the new path.
331
+ * If we don't write to a file, fall back to same path so no
332
+ * conversion happens (because we still want it to go through most
333
+ * of the move code, which also addresses url() & @import syntax...)
334
+ */
335
+ $converter = $this->getPathConverter($source, $path ?: $source);
336
+ $css = $this->move($converter, $css);
337
+
338
+ // combine css
339
+ $content .= $css;
340
+ }
341
+
342
+ $content = $this->moveImportsToTop($content);
343
+
344
+ return $content;
345
+ }
346
+
347
+ /**
348
+ * Moving a css file should update all relative urls.
349
+ * Relative references (e.g. ../images/image.gif) in a certain css file,
350
+ * will have to be updated when a file is being saved at another location
351
+ * (e.g. ../../images/image.gif, if the new CSS file is 1 folder deeper).
352
+ *
353
+ * @param ConverterInterface $converter Relative path converter
354
+ * @param string $content The CSS content to update relative urls for
355
+ *
356
+ * @return string
357
+ */
358
+ protected function move(ConverterInterface $converter, $content)
359
+ {
360
+ /*
361
+ * Relative path references will usually be enclosed by url(). @import
362
+ * is an exception, where url() is not necessary around the path (but is
363
+ * allowed).
364
+ * This *could* be 1 regular expression, where both regular expressions
365
+ * in this array are on different sides of a |. But we're using named
366
+ * patterns in both regexes, the same name on both regexes. This is only
367
+ * possible with a (?J) modifier, but that only works after a fairly
368
+ * recent PCRE version. That's why I'm doing 2 separate regular
369
+ * expressions & combining the matches after executing of both.
370
+ */
371
+ $relativeRegexes = array(
372
+ // url(xxx)
373
+ '/
374
+ # open url()
375
+ url\(
376
+
377
+ \s*
378
+
379
+ # open path enclosure
380
+ (?P<quotes>["\'])?
381
+
382
+ # fetch path
383
+ (?P<path>.+?)
384
+
385
+ # close path enclosure
386
+ (?(quotes)(?P=quotes))
387
+
388
+ \s*
389
+
390
+ # close url()
391
+ \)
392
+
393
+ /ix',
394
+
395
+ // @import "xxx"
396
+ '/
397
+ # import statement
398
+ @import
399
+
400
+ # whitespace
401
+ \s+
402
+
403
+ # we don\'t have to check for @import url(), because the
404
+ # condition above will already catch these
405
+
406
+ # open path enclosure
407
+ (?P<quotes>["\'])
408
+
409
+ # fetch path
410
+ (?P<path>.+?)
411
+
412
+ # close path enclosure
413
+ (?P=quotes)
414
+
415
+ /ix',
416
+ );
417
+
418
+ // find all relative urls in css
419
+ $matches = array();
420
+ foreach ($relativeRegexes as $relativeRegex) {
421
+ if (preg_match_all($relativeRegex, $content, $regexMatches, PREG_SET_ORDER)) {
422
+ $matches = array_merge($matches, $regexMatches);
423
+ }
424
+ }
425
+
426
+ $search = array();
427
+ $replace = array();
428
+
429
+ // loop all urls
430
+ foreach ($matches as $match) {
431
+ // determine if it's a url() or an @import match
432
+ $type = (strpos($match[0], '@import') === 0 ? 'import' : 'url');
433
+
434
+ $url = $match['path'];
435
+ if ($this->canImportByPath($url)) {
436
+ // attempting to interpret GET-params makes no sense, so let's discard them for awhile
437
+ $params = strrchr($url, '?');
438
+ $url = $params ? substr($url, 0, -strlen($params)) : $url;
439
+
440
+ // fix relative url
441
+ $url = $converter->convert($url);
442
+
443
+ // now that the path has been converted, re-apply GET-params
444
+ $url .= $params;
445
+ }
446
+
447
+ /*
448
+ * Urls with control characters above 0x7e should be quoted.
449
+ * According to Mozilla's parser, whitespace is only allowed at the
450
+ * end of unquoted urls.
451
+ * Urls with `)` (as could happen with data: uris) should also be
452
+ * quoted to avoid being confused for the url() closing parentheses.
453
+ * And urls with a # have also been reported to cause issues.
454
+ * Urls with quotes inside should also remain escaped.
455
+ *
456
+ * @see https://developer.mozilla.org/nl/docs/Web/CSS/url#The_url()_functional_notation
457
+ * @see https://hg.mozilla.org/mozilla-central/rev/14abca4e7378
458
+ * @see https://github.com/matthiasmullie/minify/issues/193
459
+ */
460
+ $url = trim($url);
461
+ if (preg_match('/[\s\)\'"#\x{7f}-\x{9f}]/u', $url)) {
462
+ $url = $match['quotes'] . $url . $match['quotes'];
463
+ }
464
+
465
+ // build replacement
466
+ $search[] = $match[0];
467
+ if ($type === 'url') {
468
+ $replace[] = 'url('.$url.')';
469
+ } elseif ($type === 'import') {
470
+ $replace[] = '@import "'.$url.'"';
471
+ }
472
+ }
473
+
474
+ // replace urls
475
+ return str_replace($search, $replace, $content);
476
+ }
477
+
478
+ /**
479
+ * Shorthand hex color codes.
480
+ * #FF0000 -> #F00.
481
+ *
482
+ * @param string $content The CSS content to shorten the hex color codes for
483
+ *
484
+ * @return string
485
+ */
486
+ protected function shortenColors($content)
487
+ {
488
+ $content = preg_replace('/(?<=[: ])#([0-9a-z])\\1([0-9a-z])\\2([0-9a-z])\\3(?:([0-9a-z])\\4)?(?=[; }])/i', '#$1$2$3$4', $content);
489
+
490
+ // remove alpha channel if it's pointless...
491
+ $content = preg_replace('/(?<=[: ])#([0-9a-z]{6})ff?(?=[; }])/i', '#$1', $content);
492
+ $content = preg_replace('/(?<=[: ])#([0-9a-z]{3})f?(?=[; }])/i', '#$1', $content);
493
+
494
+ $colors = array(
495
+ // we can shorten some even more by replacing them with their color name
496
+ '#F0FFFF' => 'azure',
497
+ '#F5F5DC' => 'beige',
498
+ '#A52A2A' => 'brown',
499
+ '#FF7F50' => 'coral',
500
+ '#FFD700' => 'gold',
501
+ '#808080' => 'gray',
502
+ '#008000' => 'green',
503
+ '#4B0082' => 'indigo',
504
+ '#FFFFF0' => 'ivory',
505
+ '#F0E68C' => 'khaki',
506
+ '#FAF0E6' => 'linen',
507
+ '#800000' => 'maroon',
508
+ '#000080' => 'navy',
509
+ '#808000' => 'olive',
510
+ '#CD853F' => 'peru',
511
+ '#FFC0CB' => 'pink',
512
+ '#DDA0DD' => 'plum',
513
+ '#800080' => 'purple',
514
+ '#F00' => 'red',
515
+ '#FA8072' => 'salmon',
516
+ '#A0522D' => 'sienna',
517
+ '#C0C0C0' => 'silver',
518
+ '#FFFAFA' => 'snow',
519
+ '#D2B48C' => 'tan',
520
+ '#FF6347' => 'tomato',
521
+ '#EE82EE' => 'violet',
522
+ '#F5DEB3' => 'wheat',
523
+ // or the other way around
524
+ 'WHITE' => '#fff',
525
+ 'BLACK' => '#000',
526
+ );
527
+
528
+ return preg_replace_callback(
529
+ '/(?<=[: ])('.implode('|', array_keys($colors)).')(?=[; }])/i',
530
+ function ($match) use ($colors) {
531
+ return $colors[strtoupper($match[0])];
532
+ },
533
+ $content
534
+ );
535
+ }
536
+
537
+ /**
538
+ * Shorten CSS font weights.
539
+ *
540
+ * @param string $content The CSS content to shorten the font weights for
541
+ *
542
+ * @return string
543
+ */
544
+ protected function shortenFontWeights($content)
545
+ {
546
+ $weights = array(
547
+ 'normal' => 400,
548
+ 'bold' => 700,
549
+ );
550
+
551
+ $callback = function ($match) use ($weights) {
552
+ return $match[1].$weights[$match[2]];
553
+ };
554
+
555
+ return preg_replace_callback('/(font-weight\s*:\s*)('.implode('|', array_keys($weights)).')(?=[;}])/', $callback, $content);
556
+ }
557
+
558
+ /**
559
+ * Shorthand 0 values to plain 0, instead of e.g. -0em.
560
+ *
561
+ * @param string $content The CSS content to shorten the zero values for
562
+ *
563
+ * @return string
564
+ */
565
+ protected function shortenZeroes($content)
566
+ {
567
+ // we don't want to strip units in `calc()` expressions:
568
+ // `5px - 0px` is valid, but `5px - 0` is not
569
+ // `10px * 0` is valid (equates to 0), and so is `10 * 0px`, but
570
+ // `10 * 0` is invalid
571
+ // we've extracted calcs earlier, so we don't need to worry about this
572
+
573
+ // reusable bits of code throughout these regexes:
574
+ // before & after are used to make sure we don't match lose unintended
575
+ // 0-like values (e.g. in #000, or in http://url/1.0)
576
+ // units can be stripped from 0 values, or used to recognize non 0
577
+ // values (where wa may be able to strip a .0 suffix)
578
+ $before = '(?<=[:(, ])';
579
+ $after = '(?=[ ,);}])';
580
+ $units = '(em|ex|%|px|cm|mm|in|pt|pc|ch|rem|vh|vw|vmin|vmax|vm)';
581
+
582
+ // strip units after zeroes (0px -> 0)
583
+ // NOTE: it should be safe to remove all units for a 0 value, but in
584
+ // practice, Webkit (especially Safari) seems to stumble over at least
585
+ // 0%, potentially other units as well. Only stripping 'px' for now.
586
+ // @see https://github.com/matthiasmullie/minify/issues/60
587
+ $content = preg_replace('/'.$before.'(-?0*(\.0+)?)(?<=0)px'.$after.'/', '\\1', $content);
588
+
589
+ // strip 0-digits (.0 -> 0)
590
+ $content = preg_replace('/'.$before.'\.0+'.$units.'?'.$after.'/', '0\\1', $content);
591
+ // strip trailing 0: 50.10 -> 50.1, 50.10px -> 50.1px
592
+ $content = preg_replace('/'.$before.'(-?[0-9]+\.[0-9]+)0+'.$units.'?'.$after.'/', '\\1\\2', $content);
593
+ // strip trailing 0: 50.00 -> 50, 50.00px -> 50px
594
+ $content = preg_replace('/'.$before.'(-?[0-9]+)\.0+'.$units.'?'.$after.'/', '\\1\\2', $content);
595
+ // strip leading 0: 0.1 -> .1, 01.1 -> 1.1
596
+ $content = preg_replace('/'.$before.'(-?)0+([0-9]*\.[0-9]+)'.$units.'?'.$after.'/', '\\1\\2\\3', $content);
597
+
598
+ // strip negative zeroes (-0 -> 0) & truncate zeroes (00 -> 0)
599
+ $content = preg_replace('/'.$before.'-?0+'.$units.'?'.$after.'/', '0\\1', $content);
600
+
601
+ // IE doesn't seem to understand a unitless flex-basis value (correct -
602
+ // it goes against the spec), so let's add it in again (make it `%`,
603
+ // which is only 1 char: 0%, 0px, 0 anything, it's all just the same)
604
+ // @see https://developer.mozilla.org/nl/docs/Web/CSS/flex
605
+ $content = preg_replace('/flex:([0-9]+\s[0-9]+\s)0([;\}])/', 'flex:${1}0%${2}', $content);
606
+ $content = preg_replace('/flex-basis:0([;\}])/', 'flex-basis:0%${1}', $content);
607
+
608
+ return $content;
609
+ }
610
+
611
+ /**
612
+ * Strip empty tags from source code.
613
+ *
614
+ * @param string $content
615
+ *
616
+ * @return string
617
+ */
618
+ protected function stripEmptyTags($content)
619
+ {
620
+ $content = preg_replace('/(?<=^)[^\{\};]+\{\s*\}/', '', $content);
621
+ $content = preg_replace('/(?<=(\}|;))[^\{\};]+\{\s*\}/', '', $content);
622
+
623
+ return $content;
624
+ }
625
+
626
+ /**
627
+ * Strip comments from source code.
628
+ */
629
+ protected function stripComments()
630
+ {
631
+ // PHP only supports $this inside anonymous functions since 5.4
632
+ $minifier = $this;
633
+ $callback = function ($match) use ($minifier) {
634
+ $count = count($minifier->extracted);
635
+ $placeholder = '/*'.$count.'*/';
636
+ $minifier->extracted[$placeholder] = $match[0];
637
+
638
+ return $placeholder;
639
+ };
640
+ $this->registerPattern('/\n?\/\*(!|.*?@license|.*?@preserve).*?\*\/\n?/s', $callback);
641
+
642
+ $this->registerPattern('/\/\*.*?\*\//s', '');
643
+ }
644
+
645
+ /**
646
+ * Strip whitespace.
647
+ *
648
+ * @param string $content The CSS content to strip the whitespace for
649
+ *
650
+ * @return string
651
+ */
652
+ protected function stripWhitespace($content)
653
+ {
654
+ // remove leading & trailing whitespace
655
+ $content = preg_replace('/^\s*/m', '', $content);
656
+ $content = preg_replace('/\s*$/m', '', $content);
657
+
658
+ // replace newlines with a single space
659
+ $content = preg_replace('/\s+/', ' ', $content);
660
+
661
+ // remove whitespace around meta characters
662
+ // inspired by stackoverflow.com/questions/15195750/minify-compress-css-with-regex
663
+ $content = preg_replace('/\s*([\*$~^|]?+=|[{};,>~]|!important\b)\s*/', '$1', $content);
664
+ $content = preg_replace('/([\[(:>\+])\s+/', '$1', $content);
665
+ $content = preg_replace('/\s+([\]\)>\+])/', '$1', $content);
666
+ $content = preg_replace('/\s+(:)(?![^\}]*\{)/', '$1', $content);
667
+
668
+ // whitespace around + and - can only be stripped inside some pseudo-
669
+ // classes, like `:nth-child(3+2n)`
670
+ // not in things like `calc(3px + 2px)`, shorthands like `3px -2px`, or
671
+ // selectors like `div.weird- p`
672
+ $pseudos = array('nth-child', 'nth-last-child', 'nth-last-of-type', 'nth-of-type');
673
+ $content = preg_replace('/:('.implode('|', $pseudos).')\(\s*([+-]?)\s*(.+?)\s*([+-]?)\s*(.*?)\s*\)/', ':$1($2$3$4$5)', $content);
674
+
675
+ // remove semicolon/whitespace followed by closing bracket
676
+ $content = str_replace(';}', '}', $content);
677
+
678
+ return trim($content);
679
+ }
680
+
681
+ /**
682
+ * Replace all occurrences of functions that may contain math, where
683
+ * whitespace around operators needs to be preserved (e.g. calc, clamp)
684
+ */
685
+ protected function extractMath()
686
+ {
687
+ $functions = array('calc', 'clamp', 'min', 'max');
688
+ $pattern = '/\b('. implode('|', $functions) .')(\(.+?)(?=$|;|})/m';
689
+
690
+ // PHP only supports $this inside anonymous functions since 5.4
691
+ $minifier = $this;
692
+ $callback = function ($match) use ($minifier, $pattern, &$callback) {
693
+ $function = $match[1];
694
+ $length = strlen($match[2]);
695
+ $expr = '';
696
+ $opened = 0;
697
+
698
+ // the regular expression for extracting math has 1 significant problem:
699
+ // it can't determine the correct closing parenthesis...
700
+ // instead, it'll match a larger portion of code to where it's certain that
701
+ // the calc() musts have ended, and we'll figure out which is the correct
702
+ // closing parenthesis here, by counting how many have opened
703
+ for ($i = 0; $i < $length; $i++) {
704
+ $char = $match[2][$i];
705
+ $expr .= $char;
706
+ if ($char === '(') {
707
+ $opened++;
708
+ } elseif ($char === ')' && --$opened === 0) {
709
+ break;
710
+ }
711
+ }
712
+
713
+ // now that we've figured out where the calc() starts and ends, extract it
714
+ $count = count($minifier->extracted);
715
+ $placeholder = 'math('.$count.')';
716
+ $minifier->extracted[$placeholder] = $function.'('.trim(substr($expr, 1, -1)).')';
717
+
718
+ // and since we've captured more code than required, we may have some leftover
719
+ // calc() in here too - go recursive on the remaining but of code to go figure
720
+ // that out and extract what is needed
721
+ $rest = str_replace($function.$expr, '', $match[0]);
722
+ $rest = preg_replace_callback($pattern, $callback, $rest);
723
+
724
+ return $placeholder.$rest;
725
+ };
726
+
727
+ $this->registerPattern($pattern, $callback);
728
+ }
729
+
730
+ /**
731
+ * Replace custom properties, whose values may be used in scenarios where
732
+ * we wouldn't want them to be minified (e.g. inside calc)
733
+ */
734
+ protected function extractCustomProperties()
735
+ {
736
+ // PHP only supports $this inside anonymous functions since 5.4
737
+ $minifier = $this;
738
+ $this->registerPattern(
739
+ '/(?<=^|[;}])(--[^:;{}"\'\s]+)\s*:([^;{}]+)/m',
740
+ function ($match) use ($minifier) {
741
+ $placeholder = '--custom-'. count($minifier->extracted) . ':0';
742
+ $minifier->extracted[$placeholder] = $match[1] .':'. trim($match[2]);
743
+ return $placeholder;
744
+
745
+ }
746
+ );
747
+ }
748
+
749
+ /**
750
+ * Check if file is small enough to be imported.
751
+ *
752
+ * @param string $path The path to the file
753
+ *
754
+ * @return bool
755
+ */
756
+ protected function canImportBySize($path)
757
+ {
758
+ return ($size = @filesize($path)) && $size <= $this->maxImportSize * 1024;
759
+ }
760
+
761
+ /**
762
+ * Check if file a file can be imported, going by the path.
763
+ *
764
+ * @param string $path
765
+ *
766
+ * @return bool
767
+ */
768
+ protected function canImportByPath($path)
769
+ {
770
+ return preg_match('/^(data:|https?:|\\/)/', $path) === 0;
771
+ }
772
+
773
+ /**
774
+ * Return a converter to update relative paths to be relative to the new
775
+ * destination.
776
+ *
777
+ * @param string $source
778
+ * @param string $target
779
+ *
780
+ * @return ConverterInterface
781
+ */
782
+ protected function getPathConverter($source, $target)
783
+ {
784
+ return new Converter($source, $target);
785
+ }
786
+ }
vendor/minifier/minify/src/Exception.php CHANGED
@@ -1,20 +1,20 @@
1
- <?php
2
- /**
3
- * Base Exception
4
- *
5
- * @deprecated Use Exceptions\BasicException instead
6
- *
7
- * @author Matthias Mullie <minify@mullie.eu>
8
- */
9
- namespace MatthiasMullie\Minify;
10
-
11
- /**
12
- * Base Exception Class
13
- * @deprecated Use Exceptions\BasicException instead
14
- *
15
- * @package Minify
16
- * @author Matthias Mullie <minify@mullie.eu>
17
- */
18
- abstract class Exception extends \Exception
19
- {
20
- }
1
+ <?php
2
+ /**
3
+ * Base Exception
4
+ *
5
+ * @deprecated Use Exceptions\BasicException instead
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ */
9
+ namespace MatthiasMullie\Minify;
10
+
11
+ /**
12
+ * Base Exception Class
13
+ * @deprecated Use Exceptions\BasicException instead
14
+ *
15
+ * @package Minify
16
+ * @author Matthias Mullie <minify@mullie.eu>
17
+ */
18
+ abstract class Exception extends \Exception
19
+ {
20
+ }
vendor/minifier/minify/src/Exceptions/BasicException.php CHANGED
@@ -1,23 +1,23 @@
1
- <?php
2
- /**
3
- * Basic exception
4
- *
5
- * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
- *
7
- * @author Matthias Mullie <minify@mullie.eu>
8
- * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
- * @license MIT License
10
- */
11
- namespace MatthiasMullie\Minify\Exceptions;
12
-
13
- use MatthiasMullie\Minify\Exception;
14
-
15
- /**
16
- * Basic Exception Class
17
- *
18
- * @package Minify\Exception
19
- * @author Matthias Mullie <minify@mullie.eu>
20
- */
21
- abstract class BasicException extends Exception
22
- {
23
- }
1
+ <?php
2
+ /**
3
+ * Basic exception
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
+ namespace MatthiasMullie\Minify\Exceptions;
12
+
13
+ use MatthiasMullie\Minify\Exception;
14
+
15
+ /**
16
+ * Basic Exception Class
17
+ *
18
+ * @package Minify\Exception
19
+ * @author Matthias Mullie <minify@mullie.eu>
20
+ */
21
+ abstract class BasicException extends Exception
22
+ {
23
+ }
vendor/minifier/minify/src/Exceptions/FileImportException.php CHANGED
@@ -1,21 +1,21 @@
1
- <?php
2
- /**
3
- * File Import Exception
4
- *
5
- * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
- *
7
- * @author Matthias Mullie <minify@mullie.eu>
8
- * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
- * @license MIT License
10
- */
11
- namespace MatthiasMullie\Minify\Exceptions;
12
-
13
- /**
14
- * File Import Exception Class
15
- *
16
- * @package Minify\Exception
17
- * @author Matthias Mullie <minify@mullie.eu>
18
- */
19
- class FileImportException extends BasicException
20
- {
21
- }
1
+ <?php
2
+ /**
3
+ * File Import Exception
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
+ namespace MatthiasMullie\Minify\Exceptions;
12
+
13
+ /**
14
+ * File Import Exception Class
15
+ *
16
+ * @package Minify\Exception
17
+ * @author Matthias Mullie <minify@mullie.eu>
18
+ */
19
+ class FileImportException extends BasicException
20
+ {
21
+ }
vendor/minifier/minify/src/Exceptions/IOException.php CHANGED
@@ -1,21 +1,21 @@
1
- <?php
2
- /**
3
- * IO Exception
4
- *
5
- * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
- *
7
- * @author Matthias Mullie <minify@mullie.eu>
8
- * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
- * @license MIT License
10
- */
11
- namespace MatthiasMullie\Minify\Exceptions;
12
-
13
- /**
14
- * IO Exception Class
15
- *
16
- * @package Minify\Exception
17
- * @author Matthias Mullie <minify@mullie.eu>
18
- */
19
- class IOException extends BasicException
20
- {
21
- }
1
+ <?php
2
+ /**
3
+ * IO Exception
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
+ namespace MatthiasMullie\Minify\Exceptions;
12
+
13
+ /**
14
+ * IO Exception Class
15
+ *
16
+ * @package Minify\Exception
17
+ * @author Matthias Mullie <minify@mullie.eu>
18
+ */
19
+ class IOException extends BasicException
20
+ {
21
+ }
vendor/minifier/minify/src/JS.php CHANGED
@@ -1,612 +1,612 @@
1
- <?php
2
- /**
3
- * JavaScript minifier
4
- *
5
- * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
- *
7
- * @author Matthias Mullie <minify@mullie.eu>
8
- * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
- * @license MIT License
10
- */
11
- namespace MatthiasMullie\Minify;
12
-
13
- /**
14
- * JavaScript Minifier Class
15
- *
16
- * Please report bugs on https://github.com/matthiasmullie/minify/issues
17
- *
18
- * @package Minify
19
- * @author Matthias Mullie <minify@mullie.eu>
20
- * @author Tijs Verkoyen <minify@verkoyen.eu>
21
- * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
22
- * @license MIT License
23
- */
24
- class JS extends Minify
25
- {
26
- /**
27
- * Var-matching regex based on http://stackoverflow.com/a/9337047/802993.
28
- *
29
- * Note that regular expressions using that bit must have the PCRE_UTF8
30
- * pattern modifier (/u) set.
31
- *
32
- * @var string
33
- */
34
- const REGEX_VARIABLE = '\b[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}0-9\x{0300}-\x{036f}\x{0483}-\x{0487}\x{0591}-\x{05bd}\x{05bf}\x{05c1}\x{05c2}\x{05c4}\x{05c5}\x{05c7}\x{0610}-\x{061a}\x{064b}-\x{0669}\x{0670}\x{06d6}-\x{06dc}\x{06df}-\x{06e4}\x{06e7}\x{06e8}\x{06ea}-\x{06ed}\x{06f0}-\x{06f9}\x{0711}\x{0730}-\x{074a}\x{07a6}-\x{07b0}\x{07c0}-\x{07c9}\x{07eb}-\x{07f3}\x{0816}-\x{0819}\x{081b}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082d}\x{0859}-\x{085b}\x{08e4}-\x{08fe}\x{0900}-\x{0903}\x{093a}-\x{093c}\x{093e}-\x{094f}\x{0951}-\x{0957}\x{0962}\x{0963}\x{0966}-\x{096f}\x{0981}-\x{0983}\x{09bc}\x{09be}-\x{09c4}\x{09c7}\x{09c8}\x{09cb}-\x{09cd}\x{09d7}\x{09e2}\x{09e3}\x{09e6}-\x{09ef}\x{0a01}-\x{0a03}\x{0a3c}\x{0a3e}-\x{0a42}\x{0a47}\x{0a48}\x{0a4b}-\x{0a4d}\x{0a51}\x{0a66}-\x{0a71}\x{0a75}\x{0a81}-\x{0a83}\x{0abc}\x{0abe}-\x{0ac5}\x{0ac7}-\x{0ac9}\x{0acb}-\x{0acd}\x{0ae2}\x{0ae3}\x{0ae6}-\x{0aef}\x{0b01}-\x{0b03}\x{0b3c}\x{0b3e}-\x{0b44}\x{0b47}\x{0b48}\x{0b4b}-\x{0b4d}\x{0b56}\x{0b57}\x{0b62}\x{0b63}\x{0b66}-\x{0b6f}\x{0b82}\x{0bbe}-\x{0bc2}\x{0bc6}-\x{0bc8}\x{0bca}-\x{0bcd}\x{0bd7}\x{0be6}-\x{0bef}\x{0c01}-\x{0c03}\x{0c3e}-\x{0c44}\x{0c46}-\x{0c48}\x{0c4a}-\x{0c4d}\x{0c55}\x{0c56}\x{0c62}\x{0c63}\x{0c66}-\x{0c6f}\x{0c82}\x{0c83}\x{0cbc}\x{0cbe}-\x{0cc4}\x{0cc6}-\x{0cc8}\x{0cca}-\x{0ccd}\x{0cd5}\x{0cd6}\x{0ce2}\x{0ce3}\x{0ce6}-\x{0cef}\x{0d02}\x{0d03}\x{0d3e}-\x{0d44}\x{0d46}-\x{0d48}\x{0d4a}-\x{0d4d}\x{0d57}\x{0d62}\x{0d63}\x{0d66}-\x{0d6f}\x{0d82}\x{0d83}\x{0dca}\x{0dcf}-\x{0dd4}\x{0dd6}\x{0dd8}-\x{0ddf}\x{0df2}\x{0df3}\x{0e31}\x{0e34}-\x{0e3a}\x{0e47}-\x{0e4e}\x{0e50}-\x{0e59}\x{0eb1}\x{0eb4}-\x{0eb9}\x{0ebb}\x{0ebc}\x{0ec8}-\x{0ecd}\x{0ed0}-\x{0ed9}\x{0f18}\x{0f19}\x{0f20}-\x{0f29}\x{0f35}\x{0f37}\x{0f39}\x{0f3e}\x{0f3f}\x{0f71}-\x{0f84}\x{0f86}\x{0f87}\x{0f8d}-\x{0f97}\x{0f99}-\x{0fbc}\x{0fc6}\x{102b}-\x{103e}\x{1040}-\x{1049}\x{1056}-\x{1059}\x{105e}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106d}\x{1071}-\x{1074}\x{1082}-\x{108d}\x{108f}-\x{109d}\x{135d}-\x{135f}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17d3}\x{17dd}\x{17e0}-\x{17e9}\x{180b}-\x{180d}\x{1810}-\x{1819}\x{18a9}\x{1920}-\x{192b}\x{1930}-\x{193b}\x{1946}-\x{194f}\x{19b0}-\x{19c0}\x{19c8}\x{19c9}\x{19d0}-\x{19d9}\x{1a17}-\x{1a1b}\x{1a55}-\x{1a5e}\x{1a60}-\x{1a7c}\x{1a7f}-\x{1a89}\x{1a90}-\x{1a99}\x{1b00}-\x{1b04}\x{1b34}-\x{1b44}\x{1b50}-\x{1b59}\x{1b6b}-\x{1b73}\x{1b80}-\x{1b82}\x{1ba1}-\x{1bad}\x{1bb0}-\x{1bb9}\x{1be6}-\x{1bf3}\x{1c24}-\x{1c37}\x{1c40}-\x{1c49}\x{1c50}-\x{1c59}\x{1cd0}-\x{1cd2}\x{1cd4}-\x{1ce8}\x{1ced}\x{1cf2}-\x{1cf4}\x{1dc0}-\x{1de6}\x{1dfc}-\x{1dff}\x{200c}\x{200d}\x{203f}\x{2040}\x{2054}\x{20d0}-\x{20dc}\x{20e1}\x{20e5}-\x{20f0}\x{2cef}-\x{2cf1}\x{2d7f}\x{2de0}-\x{2dff}\x{302a}-\x{302f}\x{3099}\x{309a}\x{a620}-\x{a629}\x{a66f}\x{a674}-\x{a67d}\x{a69f}\x{a6f0}\x{a6f1}\x{a802}\x{a806}\x{a80b}\x{a823}-\x{a827}\x{a880}\x{a881}\x{a8b4}-\x{a8c4}\x{a8d0}-\x{a8d9}\x{a8e0}-\x{a8f1}\x{a900}-\x{a909}\x{a926}-\x{a92d}\x{a947}-\x{a953}\x{a980}-\x{a983}\x{a9b3}-\x{a9c0}\x{a9d0}-\x{a9d9}\x{aa29}-\x{aa36}\x{aa43}\x{aa4c}\x{aa4d}\x{aa50}-\x{aa59}\x{aa7b}\x{aab0}\x{aab2}-\x{aab4}\x{aab7}\x{aab8}\x{aabe}\x{aabf}\x{aac1}\x{aaeb}-\x{aaef}\x{aaf5}\x{aaf6}\x{abe3}-\x{abea}\x{abec}\x{abed}\x{abf0}-\x{abf9}\x{fb1e}\x{fe00}-\x{fe0f}\x{fe20}-\x{fe26}\x{fe33}\x{fe34}\x{fe4d}-\x{fe4f}\x{ff10}-\x{ff19}\x{ff3f}]*\b';
35
-
36
- /**
37
- * Full list of JavaScript reserved words.
38
- * Will be loaded from /data/js/keywords_reserved.txt.
39
- *
40
- * @see https://mathiasbynens.be/notes/reserved-keywords
41
- *
42
- * @var string[]
43
- */
44
- protected $keywordsReserved = array();
45
-
46
- /**
47
- * List of JavaScript reserved words that accept a <variable, value, ...>
48
- * after them. Some end of lines are not the end of a statement, like with
49
- * these keywords.
50
- *
51
- * E.g.: we shouldn't insert a ; after this else
52
- * else
53
- * console.log('this is quite fine')
54
- *
55
- * Will be loaded from /data/js/keywords_before.txt
56
- *
57
- * @var string[]
58
- */
59
- protected $keywordsBefore = array();
60
-
61
- /**
62
- * List of JavaScript reserved words that accept a <variable, value, ...>
63
- * before them. Some end of lines are not the end of a statement, like when
64
- * continued by one of these keywords on the newline.
65
- *
66
- * E.g.: we shouldn't insert a ; before this instanceof
67
- * variable
68
- * instanceof String
69
- *
70
- * Will be loaded from /data/js/keywords_after.txt
71
- *
72
- * @var string[]
73
- */
74
- protected $keywordsAfter = array();
75
-
76
- /**
77
- * List of all JavaScript operators.
78
- *
79
- * Will be loaded from /data/js/operators.txt
80
- *
81
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
82
- *
83
- * @var string[]
84
- */
85
- protected $operators = array();
86
-
87
- /**
88
- * List of JavaScript operators that accept a <variable, value, ...> after
89
- * them. Some end of lines are not the end of a statement, like with these
90
- * operators.
91
- *
92
- * Note: Most operators are fine, we've only removed ++ and --.
93
- * ++ & -- have to be joined with the value they're in-/decrementing.
94
- *
95
- * Will be loaded from /data/js/operators_before.txt
96
- *
97
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
98
- *
99
- * @var string[]
100
- */
101
- protected $operatorsBefore = array();
102
-
103
- /**
104
- * List of JavaScript operators that accept a <variable, value, ...> before
105
- * them. Some end of lines are not the end of a statement, like when
106
- * continued by one of these operators on the newline.
107
- *
108
- * Note: Most operators are fine, we've only removed ), ], ++, --, ! and ~.
109
- * There can't be a newline separating ! or ~ and whatever it is negating.
110
- * ++ & -- have to be joined with the value they're in-/decrementing.
111
- * ) & ] are "special" in that they have lots or usecases. () for example
112
- * is used for function calls, for grouping, in if () and for (), ...
113
- *
114
- * Will be loaded from /data/js/operators_after.txt
115
- *
116
- * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
117
- *
118
- * @var string[]
119
- */
120
- protected $operatorsAfter = array();
121
-
122
- /**
123
- * {@inheritdoc}
124
- */
125
- public function __construct()
126
- {
127
- call_user_func_array(array('parent', '__construct'), func_get_args());
128
-
129
- $dataDir = __DIR__.'/../data/js/';
130
- $options = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES;
131
- $this->keywordsReserved = file($dataDir.'keywords_reserved.txt', $options);
132
- $this->keywordsBefore = file($dataDir.'keywords_before.txt', $options);
133
- $this->keywordsAfter = file($dataDir.'keywords_after.txt', $options);
134
- $this->operators = file($dataDir.'operators.txt', $options);
135
- $this->operatorsBefore = file($dataDir.'operators_before.txt', $options);
136
- $this->operatorsAfter = file($dataDir.'operators_after.txt', $options);
137
- }
138
-
139
- /**
140
- * Minify the data.
141
- * Perform JS optimizations.
142
- *
143
- * @param string[optional] $path Path to write the data to
144
- *
145
- * @return string The minified data
146
- */
147
- public function execute($path = null)
148
- {
149
- $content = '';
150
-
151
- /*
152
- * Let's first take out strings, comments and regular expressions.
153
- * All of these can contain JS code-like characters, and we should make
154
- * sure any further magic ignores anything inside of these.
155
- *
156
- * Consider this example, where we should not strip any whitespace:
157
- * var str = "a test";
158
- *
159
- * Comments will be removed altogether, strings and regular expressions
160
- * will be replaced by placeholder text, which we'll restore later.
161
- */
162
- $this->extractStrings('\'"`');
163
- $this->stripComments();
164
- $this->extractRegex();
165
-
166
- // loop files
167
- foreach ($this->data as $source => $js) {
168
- // take out strings, comments & regex (for which we've registered
169
- // the regexes just a few lines earlier)
170
- $js = $this->replace($js);
171
-
172
- $js = $this->propertyNotation($js);
173
- $js = $this->shortenBools($js);
174
- $js = $this->stripWhitespace($js);
175
-
176
- // combine js: separating the scripts by a ;
177
- $content .= $js.";";
178
- }
179
-
180
- // clean up leftover `;`s from the combination of multiple scripts
181
- $content = ltrim($content, ';');
182
- $content = (string) substr($content, 0, -1);
183
-
184
- /*
185
- * Earlier, we extracted strings & regular expressions and replaced them
186
- * with placeholder text. This will restore them.
187
- */
188
- $content = $this->restoreExtractedData($content);
189
-
190
- return $content;
191
- }
192
-
193
- /**
194
- * Strip comments from source code.
195
- */
196
- protected function stripComments()
197
- {
198
- // PHP only supports $this inside anonymous functions since 5.4
199
- $minifier = $this;
200
- $callback = function ($match) use ($minifier) {
201
- $count = count($minifier->extracted);
202
- $placeholder = '/*'.$count.'*/';
203
- $minifier->extracted[$placeholder] = $match[0];
204
-
205
- return $placeholder;
206
- };
207
- // multi-line comments
208
- $this->registerPattern('/\n?\/\*(!|.*?@license|.*?@preserve).*?\*\/\n?/s', $callback);
209
- $this->registerPattern('/\/\*.*?\*\//s', '');
210
-
211
- // single-line comments
212
- $this->registerPattern('/\/\/.*$/m', '');
213
- }
214
-
215
- /**
216
- * JS can have /-delimited regular expressions, like: /ab+c/.match(string).
217
- *
218
- * The content inside the regex can contain characters that may be confused
219
- * for JS code: e.g. it could contain whitespace it needs to match & we
220
- * don't want to strip whitespace in there.
221
- *
222
- * The regex can be pretty simple: we don't have to care about comments,
223
- * (which also use slashes) because stripComments() will have stripped those
224
- * already.
225
- *
226
- * This method will replace all string content with simple REGEX#
227
- * placeholder text, so we've rid all regular expressions from characters
228
- * that may be misinterpreted. Original regex content will be saved in
229
- * $this->extracted and after doing all other minifying, we can restore the
230
- * original content via restoreRegex()
231
- */
232
- protected function extractRegex()
233
- {
234
- // PHP only supports $this inside anonymous functions since 5.4
235
- $minifier = $this;
236
- $callback = function ($match) use ($minifier) {
237
- $count = count($minifier->extracted);
238
- $placeholder = '"'.$count.'"';
239
- $minifier->extracted[$placeholder] = $match[0];
240
-
241
- return $placeholder;
242
- };
243
-
244
- // match all chars except `/` and `\`
245
- // `\` is allowed though, along with whatever char follows (which is the
246
- // one being escaped)
247
- // this should allow all chars, except for an unescaped `/` (= the one
248
- // closing the regex)
249
- // then also ignore bare `/` inside `[]`, where they don't need to be
250
- // escaped: anything inside `[]` can be ignored safely
251
- $pattern = '\\/(?!\*)(?:[^\\[\\/\\\\\n\r]++|(?:\\\\.)++|(?:\\[(?:[^\\]\\\\\n\r]++|(?:\\\\.)++)++\\])++)++\\/[gimuy]*';
252
-
253
- // a regular expression can only be followed by a few operators or some
254
- // of the RegExp methods (a `\` followed by a variable or value is
255
- // likely part of a division, not a regex)
256
- $keywords = array('do', 'in', 'new', 'else', 'throw', 'yield', 'delete', 'return', 'typeof');
257
- $before = '([=:,;\+\-\*\/\}\(\{\[&\|!]|^|'.implode('|', $keywords).')\s*';
258
- $propertiesAndMethods = array(
259
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties_2
260
- 'constructor',
261
- 'flags',
262
- 'global',
263
- 'ignoreCase',
264
- 'multiline',
265
- 'source',
266
- 'sticky',
267
- 'unicode',
268
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Methods_2
269
- 'compile(',
270
- 'exec(',
271
- 'test(',
272
- 'toSource(',
273
- 'toString(',
274
- );
275
- $delimiters = array_fill(0, count($propertiesAndMethods), '/');
276
- $propertiesAndMethods = array_map('preg_quote', $propertiesAndMethods, $delimiters);
277
- $after = '(?=\s*([\.,;\)\}&\|+]|\/\/|$|\.('.implode('|', $propertiesAndMethods).')))';
278
- $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
279
-
280
- // regular expressions following a `)` are rather annoying to detect...
281
- // quite often, `/` after `)` is a division operator & if it happens to
282
- // be followed by another one (or a comment), it is likely to be
283
- // confused for a regular expression
284
- // however, it's perfectly possible for a regex to follow a `)`: after
285
- // a single-line `if()`, `while()`, ... statement, for example
286
- // since, when they occur like that, they're always the start of a
287
- // statement, there's only a limited amount of ways they can be useful:
288
- // by calling the regex methods directly
289
- // if a regex following `)` is not followed by `.<property or method>`,
290
- // it's quite likely not a regex
291
- $before = '\)\s*';
292
- $after = '(?=\s*\.('.implode('|', $propertiesAndMethods).'))';
293
- $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
294
-
295
- // 1 more edge case: a regex can be followed by a lot more operators or
296
- // keywords if there's a newline (ASI) in between, where the operator
297
- // actually starts a new statement
298
- // (https://github.com/matthiasmullie/minify/issues/56)
299
- $operators = $this->getOperatorsForRegex($this->operatorsBefore, '/');
300
- $operators += $this->getOperatorsForRegex($this->keywordsReserved, '/');
301
- $after = '(?=\s*\n\s*('.implode('|', $operators).'))';
302
- $this->registerPattern('/'.$pattern.$after.'/', $callback);
303
- }
304
-
305
- /**
306
- * Strip whitespace.
307
- *
308
- * We won't strip *all* whitespace, but as much as possible. The thing that
309
- * we'll preserve are newlines we're unsure about.
310
- * JavaScript doesn't require statements to be terminated with a semicolon.
311
- * It will automatically fix missing semicolons with ASI (automatic semi-
312
- * colon insertion) at the end of line causing errors (without semicolon.)
313
- *
314
- * Because it's sometimes hard to tell if a newline is part of a statement
315
- * that should be terminated or not, we'll just leave some of them alone.
316
- *
317
- * @param string $content The content to strip the whitespace for
318
- *
319
- * @return string
320
- */
321
- protected function stripWhitespace($content)
322
- {
323
- // uniform line endings, make them all line feed
324
- $content = str_replace(array("\r\n", "\r"), "\n", $content);
325
-
326
- // collapse all non-line feed whitespace into a single space
327
- $content = preg_replace('/[^\S\n]+/', ' ', $content);
328
-
329
- // strip leading & trailing whitespace
330
- $content = str_replace(array(" \n", "\n "), "\n", $content);
331
-
332
- // collapse consecutive line feeds into just 1
333
- $content = preg_replace('/\n+/', "\n", $content);
334
-
335
- $operatorsBefore = $this->getOperatorsForRegex($this->operatorsBefore, '/');
336
- $operatorsAfter = $this->getOperatorsForRegex($this->operatorsAfter, '/');
337
- $operators = $this->getOperatorsForRegex($this->operators, '/');
338
- $keywordsBefore = $this->getKeywordsForRegex($this->keywordsBefore, '/');
339
- $keywordsAfter = $this->getKeywordsForRegex($this->keywordsAfter, '/');
340
-
341
- // strip whitespace that ends in (or next line begin with) an operator
342
- // that allows statements to be broken up over multiple lines
343
- unset($operatorsBefore['+'], $operatorsBefore['-'], $operatorsAfter['+'], $operatorsAfter['-']);
344
- $content = preg_replace(
345
- array(
346
- '/('.implode('|', $operatorsBefore).')\s+/',
347
- '/\s+('.implode('|', $operatorsAfter).')/',
348
- ),
349
- '\\1',
350
- $content
351
- );
352
-
353
- // make sure + and - can't be mistaken for, or joined into ++ and --
354
- $content = preg_replace(
355
- array(
356
- '/(?<![\+\-])\s*([\+\-])(?![\+\-])/',
357
- '/(?<![\+\-])([\+\-])\s*(?![\+\-])/',
358
- ),
359
- '\\1',
360
- $content
361
- );
362
-
363
- // collapse whitespace around reserved words into single space
364
- $content = preg_replace('/(^|[;\}\s])\K('.implode('|', $keywordsBefore).')\s+/', '\\2 ', $content);
365
- $content = preg_replace('/\s+('.implode('|', $keywordsAfter).')(?=([;\{\s]|$))/', ' \\1', $content);
366
-
367
- /*
368
- * We didn't strip whitespace after a couple of operators because they
369
- * could be used in different contexts and we can't be sure it's ok to
370
- * strip the newlines. However, we can safely strip any non-line feed
371
- * whitespace that follows them.
372
- */
373
- $operatorsDiffBefore = array_diff($operators, $operatorsBefore);
374
- $operatorsDiffAfter = array_diff($operators, $operatorsAfter);
375
- $content = preg_replace('/('.implode('|', $operatorsDiffBefore).')[^\S\n]+/', '\\1', $content);
376
- $content = preg_replace('/[^\S\n]+('.implode('|', $operatorsDiffAfter).')/', '\\1', $content);
377
-
378
- /*
379
- * Whitespace after `return` can be omitted in a few occasions
380
- * (such as when followed by a string or regex)
381
- * Same for whitespace in between `)` and `{`, or between `{` and some
382
- * keywords.
383
- */
384
- $content = preg_replace('/\breturn\s+(["\'\/\+\-])/', 'return$1', $content);
385
- $content = preg_replace('/\)\s+\{/', '){', $content);
386
- $content = preg_replace('/}\n(else|catch|finally)\b/', '}$1', $content);
387
-
388
- /*
389
- * Get rid of double semicolons, except where they can be used like:
390
- * "for(v=1,_=b;;)", "for(v=1;;v++)" or "for(;;ja||(ja=true))".
391
- * I'll safeguard these double semicolons inside for-loops by
392
- * temporarily replacing them with an invalid condition: they won't have
393
- * a double semicolon and will be easy to spot to restore afterwards.
394
- */
395
- $content = preg_replace('/\bfor\(([^;]*);;([^;]*)\)/', 'for(\\1;-;\\2)', $content);
396
- $content = preg_replace('/;+/', ';', $content);
397
- $content = preg_replace('/\bfor\(([^;]*);-;([^;]*)\)/', 'for(\\1;;\\2)', $content);
398
-
399
- /*
400
- * Next, we'll be removing all semicolons where ASI kicks in.
401
- * for-loops however, can have an empty body (ending in only a
402
- * semicolon), like: `for(i=1;i<3;i++);`, of `for(i in list);`
403
- * Here, nothing happens during the loop; it's just used to keep
404
- * increasing `i`. With that ; omitted, the next line would be expected
405
- * to be the for-loop's body... Same goes for while loops.
406
- * I'm going to double that semicolon (if any) so after the next line,
407
- * which strips semicolons here & there, we're still left with this one.
408
- */
409
- $content = preg_replace('/(for\([^;\{]*;[^;\{]*;[^;\{]*\));(\}|$)/s', '\\1;;\\2', $content);
410
- $content = preg_replace('/(for\([^;\{]+\s+in\s+[^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
411
- /*
412
- * Below will also keep `;` after a `do{}while();` along with `while();`
413
- * While these could be stripped after do-while, detecting this
414
- * distinction is cumbersome, so I'll play it safe and make sure `;`
415
- * after any kind of `while` is kept.
416
- */
417
- $content = preg_replace('/(while\([^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
418
-
419
- /*
420
- * We also can't strip empty else-statements. Even though they're
421
- * useless and probably shouldn't be in the code in the first place, we
422
- * shouldn't be stripping the `;` that follows it as it breaks the code.
423
- * We can just remove those useless else-statements completely.
424
- *
425
- * @see https://github.com/matthiasmullie/minify/issues/91
426
- */
427
- $content = preg_replace('/else;/s', '', $content);
428
-
429
- /*
430
- * We also don't really want to terminate statements followed by closing
431
- * curly braces (which we've ignored completely up until now) or end-of-
432
- * script: ASI will kick in here & we're all about minifying.
433
- * Semicolons at beginning of the file don't make any sense either.
434
- */
435
- $content = preg_replace('/;(\}|$)/s', '\\1', $content);
436
- $content = ltrim($content, ';');
437
-
438
- // get rid of remaining whitespace af beginning/end
439
- return trim($content);
440
- }
441
-
442
- /**
443
- * We'll strip whitespace around certain operators with regular expressions.
444
- * This will prepare the given array by escaping all characters.
445
- *
446
- * @param string[] $operators
447
- * @param string $delimiter
448
- *
449
- * @return string[]
450
- */
451
- protected function getOperatorsForRegex(array $operators, $delimiter = '/')
452
- {
453
- // escape operators for use in regex
454
- $delimiters = array_fill(0, count($operators), $delimiter);
455
- $escaped = array_map('preg_quote', $operators, $delimiters);
456
-
457
- $operators = array_combine($operators, $escaped);
458
-
459
- // ignore + & - for now, they'll get special treatment
460
- unset($operators['+'], $operators['-']);
461
-
462
- // dot can not just immediately follow a number; it can be confused for
463
- // decimal point, or calling a method on it, e.g. 42 .toString()
464
- $operators['.'] = '(?<![0-9]\s)\.';
465
-
466
- // don't confuse = with other assignment shortcuts (e.g. +=)
467
- $chars = preg_quote('+-*\=<>%&|', $delimiter);
468
- $operators['='] = '(?<!['.$chars.'])\=';
469
-
470
- return $operators;
471
- }
472
-
473
- /**
474
- * We'll strip whitespace around certain keywords with regular expressions.
475
- * This will prepare the given array by escaping all characters.
476
- *
477
- * @param string[] $keywords
478
- * @param string $delimiter
479
- *
480
- * @return string[]
481
- */
482
- protected function getKeywordsForRegex(array $keywords, $delimiter = '/')
483
- {
484
- // escape keywords for use in regex
485
- $delimiter = array_fill(0, count($keywords), $delimiter);
486
- $escaped = array_map('preg_quote', $keywords, $delimiter);
487
-
488
- // add word boundaries
489
- array_walk($keywords, function ($value) {
490
- return '\b'.$value.'\b';
491
- });
492
-
493
- $keywords = array_combine($keywords, $escaped);
494
-
495
- return $keywords;
496
- }
497
-
498
- /**
499
- * Replaces all occurrences of array['key'] by array.key.
500
- *
501
- * @param string $content
502
- *
503
- * @return string
504
- */
505
- protected function propertyNotation($content)
506
- {
507
- // PHP only supports $this inside anonymous functions since 5.4
508
- $minifier = $this;
509
- $keywords = $this->keywordsReserved;
510
- $callback = function ($match) use ($minifier, $keywords) {
511
- $property = trim($minifier->extracted[$match[1]], '\'"');
512
-
513
- /*
514
- * Check if the property is a reserved keyword. In this context (as
515
- * property of an object literal/array) it shouldn't matter, but IE8
516
- * freaks out with "Expected identifier".
517
- */
518
- if (in_array($property, $keywords)) {
519
- return $match[0];
520
- }
521
-
522
- /*
523
- * See if the property is in a variable-like format (e.g.
524
- * array['key-here'] can't be replaced by array.key-here since '-'
525
- * is not a valid character there.
526
- */
527
- if (!preg_match('/^'.$minifier::REGEX_VARIABLE.'$/u', $property)) {
528
- return $match[0];
529
- }
530
-
531
- return '.'.$property;
532
- };
533
-
534
- /*
535
- * Figure out if previous character is a variable name (of the array
536
- * we want to use property notation on) - this is to make sure
537
- * standalone ['value'] arrays aren't confused for keys-of-an-array.
538
- * We can (and only have to) check the last character, because PHP's
539
- * regex implementation doesn't allow unfixed-length look-behind
540
- * assertions.
541
- */
542
- preg_match('/(\[[^\]]+\])[^\]]*$/', static::REGEX_VARIABLE, $previousChar);
543
- $previousChar = $previousChar[1];
544
-
545
- /*
546
- * Make sure word preceding the ['value'] is not a keyword, e.g.
547
- * return['x']. Because -again- PHP's regex implementation doesn't allow
548
- * unfixed-length look-behind assertions, I'm just going to do a lot of
549
- * separate look-behind assertions, one for each keyword.
550
- */
551
- $keywords = $this->getKeywordsForRegex($keywords);
552
- $keywords = '(?<!'.implode(')(?<!', $keywords).')';
553
-
554
- return preg_replace_callback('/(?<='.$previousChar.'|\])'.$keywords.'\[\s*(([\'"])[0-9]+\\2)\s*\]/u', $callback, $content);
555
- }
556
-
557
- /**
558
- * Replaces true & false by !0 and !1.
559
- *
560
- * @param string $content
561
- *
562
- * @return string
563
- */
564
- protected function shortenBools($content)
565
- {
566
- /*
567
- * 'true' or 'false' could be used as property names (which may be
568
- * followed by whitespace) - we must not replace those!
569
- * Since PHP doesn't allow variable-length (to account for the
570
- * whitespace) lookbehind assertions, I need to capture the leading
571
- * character and check if it's a `.`
572
- */
573
- $callback = function ($match) {
574
- if (trim($match[1]) === '.') {
575
- return $match[0];
576
- }
577
-
578
- return $match[1].($match[2] === 'true' ? '!0' : '!1');
579
- };
580
- $content = preg_replace_callback('/(^|.\s*)\b(true|false)\b(?!:)/', $callback, $content);
581
-
582
- // for(;;) is exactly the same as while(true), but shorter :)
583
- $content = preg_replace('/\bwhile\(!0\){/', 'for(;;){', $content);
584
-
585
- // now make sure we didn't turn any do ... while(true) into do ... for(;;)
586
- preg_match_all('/\bdo\b/', $content, $dos, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
587
-
588
- // go backward to make sure positional offsets aren't altered when $content changes
589
- $dos = array_reverse($dos);
590
- foreach ($dos as $do) {
591
- $offsetDo = $do[0][1];
592
-
593
- // find all `while` (now `for`) following `do`: one of those must be
594
- // associated with the `do` and be turned back into `while`
595
- preg_match_all('/\bfor\(;;\)/', $content, $whiles, PREG_OFFSET_CAPTURE | PREG_SET_ORDER, $offsetDo);
596
- foreach ($whiles as $while) {
597
- $offsetWhile = $while[0][1];
598
-
599
- $open = substr_count($content, '{', $offsetDo, $offsetWhile - $offsetDo);
600
- $close = substr_count($content, '}', $offsetDo, $offsetWhile - $offsetDo);
601
- if ($open === $close) {
602
- // only restore `while` if amount of `{` and `}` are the same;
603
- // otherwise, that `for` isn't associated with this `do`
604
- $content = substr_replace($content, 'while(!0)', $offsetWhile, strlen('for(;;)'));
605
- break;
606
- }
607
- }
608
- }
609
-
610
- return $content;
611
- }
612
- }
1
+ <?php
2
+ /**
3
+ * JavaScript minifier
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
+ namespace MatthiasMullie\Minify;
12
+
13
+ /**
14
+ * JavaScript Minifier Class
15
+ *
16
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
17
+ *
18
+ * @package Minify
19
+ * @author Matthias Mullie <minify@mullie.eu>
20
+ * @author Tijs Verkoyen <minify@verkoyen.eu>
21
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
22
+ * @license MIT License
23
+ */
24
+ class JS extends Minify
25
+ {
26
+ /**
27
+ * Var-matching regex based on http://stackoverflow.com/a/9337047/802993.
28
+ *
29
+ * Note that regular expressions using that bit must have the PCRE_UTF8
30
+ * pattern modifier (/u) set.
31
+ *
32
+ * @var string
33
+ */
34
+ const REGEX_VARIABLE = '\b[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\x{02c1}\x{02c6}-\x{02d1}\x{02e0}-\x{02e4}\x{02ec}\x{02ee}\x{0370}-\x{0374}\x{0376}\x{0377}\x{037a}-\x{037d}\x{0386}\x{0388}-\x{038a}\x{038c}\x{038e}-\x{03a1}\x{03a3}-\x{03f5}\x{03f7}-\x{0481}\x{048a}-\x{0527}\x{0531}-\x{0556}\x{0559}\x{0561}-\x{0587}\x{05d0}-\x{05ea}\x{05f0}-\x{05f2}\x{0620}-\x{064a}\x{066e}\x{066f}\x{0671}-\x{06d3}\x{06d5}\x{06e5}\x{06e6}\x{06ee}\x{06ef}\x{06fa}-\x{06fc}\x{06ff}\x{0710}\x{0712}-\x{072f}\x{074d}-\x{07a5}\x{07b1}\x{07ca}-\x{07ea}\x{07f4}\x{07f5}\x{07fa}\x{0800}-\x{0815}\x{081a}\x{0824}\x{0828}\x{0840}-\x{0858}\x{08a0}\x{08a2}-\x{08ac}\x{0904}-\x{0939}\x{093d}\x{0950}\x{0958}-\x{0961}\x{0971}-\x{0977}\x{0979}-\x{097f}\x{0985}-\x{098c}\x{098f}\x{0990}\x{0993}-\x{09a8}\x{09aa}-\x{09b0}\x{09b2}\x{09b6}-\x{09b9}\x{09bd}\x{09ce}\x{09dc}\x{09dd}\x{09df}-\x{09e1}\x{09f0}\x{09f1}\x{0a05}-\x{0a0a}\x{0a0f}\x{0a10}\x{0a13}-\x{0a28}\x{0a2a}-\x{0a30}\x{0a32}\x{0a33}\x{0a35}\x{0a36}\x{0a38}\x{0a39}\x{0a59}-\x{0a5c}\x{0a5e}\x{0a72}-\x{0a74}\x{0a85}-\x{0a8d}\x{0a8f}-\x{0a91}\x{0a93}-\x{0aa8}\x{0aaa}-\x{0ab0}\x{0ab2}\x{0ab3}\x{0ab5}-\x{0ab9}\x{0abd}\x{0ad0}\x{0ae0}\x{0ae1}\x{0b05}-\x{0b0c}\x{0b0f}\x{0b10}\x{0b13}-\x{0b28}\x{0b2a}-\x{0b30}\x{0b32}\x{0b33}\x{0b35}-\x{0b39}\x{0b3d}\x{0b5c}\x{0b5d}\x{0b5f}-\x{0b61}\x{0b71}\x{0b83}\x{0b85}-\x{0b8a}\x{0b8e}-\x{0b90}\x{0b92}-\x{0b95}\x{0b99}\x{0b9a}\x{0b9c}\x{0b9e}\x{0b9f}\x{0ba3}\x{0ba4}\x{0ba8}-\x{0baa}\x{0bae}-\x{0bb9}\x{0bd0}\x{0c05}-\x{0c0c}\x{0c0e}-\x{0c10}\x{0c12}-\x{0c28}\x{0c2a}-\x{0c33}\x{0c35}-\x{0c39}\x{0c3d}\x{0c58}\x{0c59}\x{0c60}\x{0c61}\x{0c85}-\x{0c8c}\x{0c8e}-\x{0c90}\x{0c92}-\x{0ca8}\x{0caa}-\x{0cb3}\x{0cb5}-\x{0cb9}\x{0cbd}\x{0cde}\x{0ce0}\x{0ce1}\x{0cf1}\x{0cf2}\x{0d05}-\x{0d0c}\x{0d0e}-\x{0d10}\x{0d12}-\x{0d3a}\x{0d3d}\x{0d4e}\x{0d60}\x{0d61}\x{0d7a}-\x{0d7f}\x{0d85}-\x{0d96}\x{0d9a}-\x{0db1}\x{0db3}-\x{0dbb}\x{0dbd}\x{0dc0}-\x{0dc6}\x{0e01}-\x{0e30}\x{0e32}\x{0e33}\x{0e40}-\x{0e46}\x{0e81}\x{0e82}\x{0e84}\x{0e87}\x{0e88}\x{0e8a}\x{0e8d}\x{0e94}-\x{0e97}\x{0e99}-\x{0e9f}\x{0ea1}-\x{0ea3}\x{0ea5}\x{0ea7}\x{0eaa}\x{0eab}\x{0ead}-\x{0eb0}\x{0eb2}\x{0eb3}\x{0ebd}\x{0ec0}-\x{0ec4}\x{0ec6}\x{0edc}-\x{0edf}\x{0f00}\x{0f40}-\x{0f47}\x{0f49}-\x{0f6c}\x{0f88}-\x{0f8c}\x{1000}-\x{102a}\x{103f}\x{1050}-\x{1055}\x{105a}-\x{105d}\x{1061}\x{1065}\x{1066}\x{106e}-\x{1070}\x{1075}-\x{1081}\x{108e}\x{10a0}-\x{10c5}\x{10c7}\x{10cd}\x{10d0}-\x{10fa}\x{10fc}-\x{1248}\x{124a}-\x{124d}\x{1250}-\x{1256}\x{1258}\x{125a}-\x{125d}\x{1260}-\x{1288}\x{128a}-\x{128d}\x{1290}-\x{12b0}\x{12b2}-\x{12b5}\x{12b8}-\x{12be}\x{12c0}\x{12c2}-\x{12c5}\x{12c8}-\x{12d6}\x{12d8}-\x{1310}\x{1312}-\x{1315}\x{1318}-\x{135a}\x{1380}-\x{138f}\x{13a0}-\x{13f4}\x{1401}-\x{166c}\x{166f}-\x{167f}\x{1681}-\x{169a}\x{16a0}-\x{16ea}\x{16ee}-\x{16f0}\x{1700}-\x{170c}\x{170e}-\x{1711}\x{1720}-\x{1731}\x{1740}-\x{1751}\x{1760}-\x{176c}\x{176e}-\x{1770}\x{1780}-\x{17b3}\x{17d7}\x{17dc}\x{1820}-\x{1877}\x{1880}-\x{18a8}\x{18aa}\x{18b0}-\x{18f5}\x{1900}-\x{191c}\x{1950}-\x{196d}\x{1970}-\x{1974}\x{1980}-\x{19ab}\x{19c1}-\x{19c7}\x{1a00}-\x{1a16}\x{1a20}-\x{1a54}\x{1aa7}\x{1b05}-\x{1b33}\x{1b45}-\x{1b4b}\x{1b83}-\x{1ba0}\x{1bae}\x{1baf}\x{1bba}-\x{1be5}\x{1c00}-\x{1c23}\x{1c4d}-\x{1c4f}\x{1c5a}-\x{1c7d}\x{1ce9}-\x{1cec}\x{1cee}-\x{1cf1}\x{1cf5}\x{1cf6}\x{1d00}-\x{1dbf}\x{1e00}-\x{1f15}\x{1f18}-\x{1f1d}\x{1f20}-\x{1f45}\x{1f48}-\x{1f4d}\x{1f50}-\x{1f57}\x{1f59}\x{1f5b}\x{1f5d}\x{1f5f}-\x{1f7d}\x{1f80}-\x{1fb4}\x{1fb6}-\x{1fbc}\x{1fbe}\x{1fc2}-\x{1fc4}\x{1fc6}-\x{1fcc}\x{1fd0}-\x{1fd3}\x{1fd6}-\x{1fdb}\x{1fe0}-\x{1fec}\x{1ff2}-\x{1ff4}\x{1ff6}-\x{1ffc}\x{2071}\x{207f}\x{2090}-\x{209c}\x{2102}\x{2107}\x{210a}-\x{2113}\x{2115}\x{2119}-\x{211d}\x{2124}\x{2126}\x{2128}\x{212a}-\x{212d}\x{212f}-\x{2139}\x{213c}-\x{213f}\x{2145}-\x{2149}\x{214e}\x{2160}-\x{2188}\x{2c00}-\x{2c2e}\x{2c30}-\x{2c5e}\x{2c60}-\x{2ce4}\x{2ceb}-\x{2cee}\x{2cf2}\x{2cf3}\x{2d00}-\x{2d25}\x{2d27}\x{2d2d}\x{2d30}-\x{2d67}\x{2d6f}\x{2d80}-\x{2d96}\x{2da0}-\x{2da6}\x{2da8}-\x{2dae}\x{2db0}-\x{2db6}\x{2db8}-\x{2dbe}\x{2dc0}-\x{2dc6}\x{2dc8}-\x{2dce}\x{2dd0}-\x{2dd6}\x{2dd8}-\x{2dde}\x{2e2f}\x{3005}-\x{3007}\x{3021}-\x{3029}\x{3031}-\x{3035}\x{3038}-\x{303c}\x{3041}-\x{3096}\x{309d}-\x{309f}\x{30a1}-\x{30fa}\x{30fc}-\x{30ff}\x{3105}-\x{312d}\x{3131}-\x{318e}\x{31a0}-\x{31ba}\x{31f0}-\x{31ff}\x{3400}-\x{4db5}\x{4e00}-\x{9fcc}\x{a000}-\x{a48c}\x{a4d0}-\x{a4fd}\x{a500}-\x{a60c}\x{a610}-\x{a61f}\x{a62a}\x{a62b}\x{a640}-\x{a66e}\x{a67f}-\x{a697}\x{a6a0}-\x{a6ef}\x{a717}-\x{a71f}\x{a722}-\x{a788}\x{a78b}-\x{a78e}\x{a790}-\x{a793}\x{a7a0}-\x{a7aa}\x{a7f8}-\x{a801}\x{a803}-\x{a805}\x{a807}-\x{a80a}\x{a80c}-\x{a822}\x{a840}-\x{a873}\x{a882}-\x{a8b3}\x{a8f2}-\x{a8f7}\x{a8fb}\x{a90a}-\x{a925}\x{a930}-\x{a946}\x{a960}-\x{a97c}\x{a984}-\x{a9b2}\x{a9cf}\x{aa00}-\x{aa28}\x{aa40}-\x{aa42}\x{aa44}-\x{aa4b}\x{aa60}-\x{aa76}\x{aa7a}\x{aa80}-\x{aaaf}\x{aab1}\x{aab5}\x{aab6}\x{aab9}-\x{aabd}\x{aac0}\x{aac2}\x{aadb}-\x{aadd}\x{aae0}-\x{aaea}\x{aaf2}-\x{aaf4}\x{ab01}-\x{ab06}\x{ab09}-\x{ab0e}\x{ab11}-\x{ab16}\x{ab20}-\x{ab26}\x{ab28}-\x{ab2e}\x{abc0}-\x{abe2}\x{ac00}-\x{d7a3}\x{d7b0}-\x{d7c6}\x{d7cb}-\x{d7fb}\x{f900}-\x{fa6d}\x{fa70}-\x{fad9}\x{fb00}-\x{fb06}\x{fb13}-\x{fb17}\x{fb1d}\x{fb1f}-\x{fb28}\x{fb2a}-\x{fb36}\x{fb38}-\x{fb3c}\x{fb3e}\x{fb40}\x{fb41}\x{fb43}\x{fb44}\x{fb46}-\x{fbb1}\x{fbd3}-\x{fd3d}\x{fd50}-\x{fd8f}\x{fd92}-\x{fdc7}\x{fdf0}-\x{fdfb}\x{fe70}-\x{fe74}\x{fe76}-\x{fefc}\x{ff21}-\x{ff3a}\x{ff41}-\x{ff5a}\x{ff66}-\x{ffbe}\x{ffc2}-\x{ffc7}\x{ffca}-\x{ffcf}\x{ffd2}-\x{ffd7}\x{ffda}-\x{ffdc}0-9\x{0300}-\x{036f}\x{0483}-\x{0487}\x{0591}-\x{05bd}\x{05bf}\x{05c1}\x{05c2}\x{05c4}\x{05c5}\x{05c7}\x{0610}-\x{061a}\x{064b}-\x{0669}\x{0670}\x{06d6}-\x{06dc}\x{06df}-\x{06e4}\x{06e7}\x{06e8}\x{06ea}-\x{06ed}\x{06f0}-\x{06f9}\x{0711}\x{0730}-\x{074a}\x{07a6}-\x{07b0}\x{07c0}-\x{07c9}\x{07eb}-\x{07f3}\x{0816}-\x{0819}\x{081b}-\x{0823}\x{0825}-\x{0827}\x{0829}-\x{082d}\x{0859}-\x{085b}\x{08e4}-\x{08fe}\x{0900}-\x{0903}\x{093a}-\x{093c}\x{093e}-\x{094f}\x{0951}-\x{0957}\x{0962}\x{0963}\x{0966}-\x{096f}\x{0981}-\x{0983}\x{09bc}\x{09be}-\x{09c4}\x{09c7}\x{09c8}\x{09cb}-\x{09cd}\x{09d7}\x{09e2}\x{09e3}\x{09e6}-\x{09ef}\x{0a01}-\x{0a03}\x{0a3c}\x{0a3e}-\x{0a42}\x{0a47}\x{0a48}\x{0a4b}-\x{0a4d}\x{0a51}\x{0a66}-\x{0a71}\x{0a75}\x{0a81}-\x{0a83}\x{0abc}\x{0abe}-\x{0ac5}\x{0ac7}-\x{0ac9}\x{0acb}-\x{0acd}\x{0ae2}\x{0ae3}\x{0ae6}-\x{0aef}\x{0b01}-\x{0b03}\x{0b3c}\x{0b3e}-\x{0b44}\x{0b47}\x{0b48}\x{0b4b}-\x{0b4d}\x{0b56}\x{0b57}\x{0b62}\x{0b63}\x{0b66}-\x{0b6f}\x{0b82}\x{0bbe}-\x{0bc2}\x{0bc6}-\x{0bc8}\x{0bca}-\x{0bcd}\x{0bd7}\x{0be6}-\x{0bef}\x{0c01}-\x{0c03}\x{0c3e}-\x{0c44}\x{0c46}-\x{0c48}\x{0c4a}-\x{0c4d}\x{0c55}\x{0c56}\x{0c62}\x{0c63}\x{0c66}-\x{0c6f}\x{0c82}\x{0c83}\x{0cbc}\x{0cbe}-\x{0cc4}\x{0cc6}-\x{0cc8}\x{0cca}-\x{0ccd}\x{0cd5}\x{0cd6}\x{0ce2}\x{0ce3}\x{0ce6}-\x{0cef}\x{0d02}\x{0d03}\x{0d3e}-\x{0d44}\x{0d46}-\x{0d48}\x{0d4a}-\x{0d4d}\x{0d57}\x{0d62}\x{0d63}\x{0d66}-\x{0d6f}\x{0d82}\x{0d83}\x{0dca}\x{0dcf}-\x{0dd4}\x{0dd6}\x{0dd8}-\x{0ddf}\x{0df2}\x{0df3}\x{0e31}\x{0e34}-\x{0e3a}\x{0e47}-\x{0e4e}\x{0e50}-\x{0e59}\x{0eb1}\x{0eb4}-\x{0eb9}\x{0ebb}\x{0ebc}\x{0ec8}-\x{0ecd}\x{0ed0}-\x{0ed9}\x{0f18}\x{0f19}\x{0f20}-\x{0f29}\x{0f35}\x{0f37}\x{0f39}\x{0f3e}\x{0f3f}\x{0f71}-\x{0f84}\x{0f86}\x{0f87}\x{0f8d}-\x{0f97}\x{0f99}-\x{0fbc}\x{0fc6}\x{102b}-\x{103e}\x{1040}-\x{1049}\x{1056}-\x{1059}\x{105e}-\x{1060}\x{1062}-\x{1064}\x{1067}-\x{106d}\x{1071}-\x{1074}\x{1082}-\x{108d}\x{108f}-\x{109d}\x{135d}-\x{135f}\x{1712}-\x{1714}\x{1732}-\x{1734}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17d3}\x{17dd}\x{17e0}-\x{17e9}\x{180b}-\x{180d}\x{1810}-\x{1819}\x{18a9}\x{1920}-\x{192b}\x{1930}-\x{193b}\x{1946}-\x{194f}\x{19b0}-\x{19c0}\x{19c8}\x{19c9}\x{19d0}-\x{19d9}\x{1a17}-\x{1a1b}\x{1a55}-\x{1a5e}\x{1a60}-\x{1a7c}\x{1a7f}-\x{1a89}\x{1a90}-\x{1a99}\x{1b00}-\x{1b04}\x{1b34}-\x{1b44}\x{1b50}-\x{1b59}\x{1b6b}-\x{1b73}\x{1b80}-\x{1b82}\x{1ba1}-\x{1bad}\x{1bb0}-\x{1bb9}\x{1be6}-\x{1bf3}\x{1c24}-\x{1c37}\x{1c40}-\x{1c49}\x{1c50}-\x{1c59}\x{1cd0}-\x{1cd2}\x{1cd4}-\x{1ce8}\x{1ced}\x{1cf2}-\x{1cf4}\x{1dc0}-\x{1de6}\x{1dfc}-\x{1dff}\x{200c}\x{200d}\x{203f}\x{2040}\x{2054}\x{20d0}-\x{20dc}\x{20e1}\x{20e5}-\x{20f0}\x{2cef}-\x{2cf1}\x{2d7f}\x{2de0}-\x{2dff}\x{302a}-\x{302f}\x{3099}\x{309a}\x{a620}-\x{a629}\x{a66f}\x{a674}-\x{a67d}\x{a69f}\x{a6f0}\x{a6f1}\x{a802}\x{a806}\x{a80b}\x{a823}-\x{a827}\x{a880}\x{a881}\x{a8b4}-\x{a8c4}\x{a8d0}-\x{a8d9}\x{a8e0}-\x{a8f1}\x{a900}-\x{a909}\x{a926}-\x{a92d}\x{a947}-\x{a953}\x{a980}-\x{a983}\x{a9b3}-\x{a9c0}\x{a9d0}-\x{a9d9}\x{aa29}-\x{aa36}\x{aa43}\x{aa4c}\x{aa4d}\x{aa50}-\x{aa59}\x{aa7b}\x{aab0}\x{aab2}-\x{aab4}\x{aab7}\x{aab8}\x{aabe}\x{aabf}\x{aac1}\x{aaeb}-\x{aaef}\x{aaf5}\x{aaf6}\x{abe3}-\x{abea}\x{abec}\x{abed}\x{abf0}-\x{abf9}\x{fb1e}\x{fe00}-\x{fe0f}\x{fe20}-\x{fe26}\x{fe33}\x{fe34}\x{fe4d}-\x{fe4f}\x{ff10}-\x{ff19}\x{ff3f}]*\b';
35
+
36
+ /**
37
+ * Full list of JavaScript reserved words.
38
+ * Will be loaded from /data/js/keywords_reserved.txt.
39
+ *
40
+ * @see https://mathiasbynens.be/notes/reserved-keywords
41
+ *
42
+ * @var string[]
43
+ */
44
+ protected $keywordsReserved = array();
45
+
46
+ /**
47
+ * List of JavaScript reserved words that accept a <variable, value, ...>
48
+ * after them. Some end of lines are not the end of a statement, like with
49
+ * these keywords.
50
+ *
51
+ * E.g.: we shouldn't insert a ; after this else
52
+ * else
53
+ * console.log('this is quite fine')
54
+ *
55
+ * Will be loaded from /data/js/keywords_before.txt
56
+ *
57
+ * @var string[]
58
+ */
59
+ protected $keywordsBefore = array();
60
+
61
+ /**
62
+ * List of JavaScript reserved words that accept a <variable, value, ...>
63
+ * before them. Some end of lines are not the end of a statement, like when
64
+ * continued by one of these keywords on the newline.
65
+ *
66
+ * E.g.: we shouldn't insert a ; before this instanceof
67
+ * variable
68
+ * instanceof String
69
+ *
70
+ * Will be loaded from /data/js/keywords_after.txt
71
+ *
72
+ * @var string[]
73
+ */
74
+ protected $keywordsAfter = array();
75
+
76
+ /**
77
+ * List of all JavaScript operators.
78
+ *
79
+ * Will be loaded from /data/js/operators.txt
80
+ *
81
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
82
+ *
83
+ * @var string[]
84
+ */
85
+ protected $operators = array();
86
+
87
+ /**
88
+ * List of JavaScript operators that accept a <variable, value, ...> after
89
+ * them. Some end of lines are not the end of a statement, like with these
90
+ * operators.
91
+ *
92
+ * Note: Most operators are fine, we've only removed ++ and --.
93
+ * ++ & -- have to be joined with the value they're in-/decrementing.
94
+ *
95
+ * Will be loaded from /data/js/operators_before.txt
96
+ *
97
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
98
+ *
99
+ * @var string[]
100
+ */
101
+ protected $operatorsBefore = array();
102
+
103
+ /**
104
+ * List of JavaScript operators that accept a <variable, value, ...> before
105
+ * them. Some end of lines are not the end of a statement, like when
106
+ * continued by one of these operators on the newline.
107
+ *
108
+ * Note: Most operators are fine, we've only removed ), ], ++, --, ! and ~.
109
+ * There can't be a newline separating ! or ~ and whatever it is negating.
110
+ * ++ & -- have to be joined with the value they're in-/decrementing.
111
+ * ) & ] are "special" in that they have lots or usecases. () for example
112
+ * is used for function calls, for grouping, in if () and for (), ...
113
+ *
114
+ * Will be loaded from /data/js/operators_after.txt
115
+ *
116
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators
117
+ *
118
+ * @var string[]
119
+ */
120
+ protected $operatorsAfter = array();
121
+
122
+ /**
123
+ * {@inheritdoc}
124
+ */
125
+ public function __construct()
126
+ {
127
+ call_user_func_array(array('parent', '__construct'), func_get_args());
128
+
129
+ $dataDir = __DIR__.'/../data/js/';
130
+ $options = FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES;
131
+ $this->keywordsReserved = file($dataDir.'keywords_reserved.txt', $options);
132
+ $this->keywordsBefore = file($dataDir.'keywords_before.txt', $options);
133
+ $this->keywordsAfter = file($dataDir.'keywords_after.txt', $options);
134
+ $this->operators = file($dataDir.'operators.txt', $options);
135
+ $this->operatorsBefore = file($dataDir.'operators_before.txt', $options);
136
+ $this->operatorsAfter = file($dataDir.'operators_after.txt', $options);
137
+ }
138
+
139
+ /**
140
+ * Minify the data.
141
+ * Perform JS optimizations.
142
+ *
143
+ * @param string[optional] $path Path to write the data to
144
+ *
145
+ * @return string The minified data
146
+ */
147
+ public function execute($path = null)
148
+ {
149
+ $content = '';
150
+
151
+ /*
152
+ * Let's first take out strings, comments and regular expressions.
153
+ * All of these can contain JS code-like characters, and we should make
154
+ * sure any further magic ignores anything inside of these.
155
+ *
156
+ * Consider this example, where we should not strip any whitespace:
157
+ * var str = "a test";
158
+ *
159
+ * Comments will be removed altogether, strings and regular expressions
160
+ * will be replaced by placeholder text, which we'll restore later.
161
+ */
162
+ $this->extractStrings('\'"`');
163
+ $this->stripComments();
164
+ $this->extractRegex();
165
+
166
+ // loop files
167
+ foreach ($this->data as $source => $js) {
168
+ // take out strings, comments & regex (for which we've registered
169
+ // the regexes just a few lines earlier)
170
+ $js = $this->replace($js);
171
+
172
+ $js = $this->propertyNotation($js);
173
+ $js = $this->shortenBools($js);
174
+ $js = $this->stripWhitespace($js);
175
+
176
+ // combine js: separating the scripts by a ;
177
+ $content .= $js.";";
178
+ }
179
+
180
+ // clean up leftover `;`s from the combination of multiple scripts
181
+ $content = ltrim($content, ';');
182
+ $content = (string) substr($content, 0, -1);
183
+
184
+ /*
185
+ * Earlier, we extracted strings & regular expressions and replaced them
186
+ * with placeholder text. This will restore them.
187
+ */
188
+ $content = $this->restoreExtractedData($content);
189
+
190
+ return $content;
191
+ }
192
+
193
+ /**
194
+ * Strip comments from source code.
195
+ */
196
+ protected function stripComments()
197
+ {
198
+ // PHP only supports $this inside anonymous functions since 5.4
199
+ $minifier = $this;
200
+ $callback = function ($match) use ($minifier) {
201
+ $count = count($minifier->extracted);
202
+ $placeholder = '/*'.$count.'*/';
203
+ $minifier->extracted[$placeholder] = $match[0];
204
+
205
+ return $placeholder;
206
+ };
207
+ // multi-line comments
208
+ $this->registerPattern('/\n?\/\*(!|.*?@license|.*?@preserve).*?\*\/\n?/s', $callback);
209
+ $this->registerPattern('/\/\*.*?\*\//s', '');
210
+
211
+ // single-line comments
212
+ $this->registerPattern('/\/\/.*$/m', '');
213
+ }
214
+
215
+ /**
216
+ * JS can have /-delimited regular expressions, like: /ab+c/.match(string).
217
+ *
218
+ * The content inside the regex can contain characters that may be confused
219
+ * for JS code: e.g. it could contain whitespace it needs to match & we
220
+ * don't want to strip whitespace in there.
221
+ *
222
+ * The regex can be pretty simple: we don't have to care about comments,
223
+ * (which also use slashes) because stripComments() will have stripped those
224
+ * already.
225
+ *
226
+ * This method will replace all string content with simple REGEX#
227
+ * placeholder text, so we've rid all regular expressions from characters
228
+ * that may be misinterpreted. Original regex content will be saved in
229
+ * $this->extracted and after doing all other minifying, we can restore the
230
+ * original content via restoreRegex()
231
+ */
232
+ protected function extractRegex()
233
+ {
234
+ // PHP only supports $this inside anonymous functions since 5.4
235
+ $minifier = $this;
236
+ $callback = function ($match) use ($minifier) {
237
+ $count = count($minifier->extracted);
238
+ $placeholder = '"'.$count.'"';
239
+ $minifier->extracted[$placeholder] = $match[0];
240
+
241
+ return $placeholder;
242
+ };
243
+
244
+ // match all chars except `/` and `\`
245
+ // `\` is allowed though, along with whatever char follows (which is the
246
+ // one being escaped)
247
+ // this should allow all chars, except for an unescaped `/` (= the one
248
+ // closing the regex)
249
+ // then also ignore bare `/` inside `[]`, where they don't need to be
250
+ // escaped: anything inside `[]` can be ignored safely
251
+ $pattern = '\\/(?!\*)(?:[^\\[\\/\\\\\n\r]++|(?:\\\\.)++|(?:\\[(?:[^\\]\\\\\n\r]++|(?:\\\\.)++)++\\])++)++\\/[gimuy]*';
252
+
253
+ // a regular expression can only be followed by a few operators or some
254
+ // of the RegExp methods (a `\` followed by a variable or value is
255
+ // likely part of a division, not a regex)
256
+ $keywords = array('do', 'in', 'new', 'else', 'throw', 'yield', 'delete', 'return', 'typeof');
257
+ $before = '(^|[=:,;\+\-\*\/\}\(\{\[&\|!]|'.implode('|', $keywords).')\s*';
258
+ $propertiesAndMethods = array(
259
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Properties_2
260
+ 'constructor',
261
+ 'flags',
262
+ 'global',
263
+ 'ignoreCase',
264
+ 'multiline',
265
+ 'source',
266
+ 'sticky',
267
+ 'unicode',
268
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Methods_2
269
+ 'compile(',
270
+ 'exec(',
271
+ 'test(',
272
+ 'toSource(',
273
+ 'toString(',
274
+ );
275
+ $delimiters = array_fill(0, count($propertiesAndMethods), '/');
276
+ $propertiesAndMethods = array_map('preg_quote', $propertiesAndMethods, $delimiters);
277
+ $after = '(?=\s*([\.,;\)\}&\|+]|\/\/|$|\.('.implode('|', $propertiesAndMethods).')))';
278
+ $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
279
+
280
+ // regular expressions following a `)` are rather annoying to detect...
281
+ // quite often, `/` after `)` is a division operator & if it happens to
282
+ // be followed by another one (or a comment), it is likely to be
283
+ // confused for a regular expression
284
+ // however, it's perfectly possible for a regex to follow a `)`: after
285
+ // a single-line `if()`, `while()`, ... statement, for example
286
+ // since, when they occur like that, they're always the start of a
287
+ // statement, there's only a limited amount of ways they can be useful:
288
+ // by calling the regex methods directly
289
+ // if a regex following `)` is not followed by `.<property or method>`,
290
+ // it's quite likely not a regex
291
+ $before = '\)\s*';
292
+ $after = '(?=\s*\.('.implode('|', $propertiesAndMethods).'))';
293
+ $this->registerPattern('/'.$before.'\K'.$pattern.$after.'/', $callback);
294
+
295
+ // 1 more edge case: a regex can be followed by a lot more operators or
296
+ // keywords if there's a newline (ASI) in between, where the operator
297
+ // actually starts a new statement
298
+ // (https://github.com/matthiasmullie/minify/issues/56)
299
+ $operators = $this->getOperatorsForRegex($this->operatorsBefore, '/');
300
+ $operators += $this->getOperatorsForRegex($this->keywordsReserved, '/');
301
+ $after = '(?=\s*\n\s*('.implode('|', $operators).'))';
302
+ $this->registerPattern('/'.$pattern.$after.'/', $callback);
303
+ }
304
+
305
+ /**
306
+ * Strip whitespace.
307
+ *
308
+ * We won't strip *all* whitespace, but as much as possible. The thing that
309
+ * we'll preserve are newlines we're unsure about.
310
+ * JavaScript doesn't require statements to be terminated with a semicolon.
311
+ * It will automatically fix missing semicolons with ASI (automatic semi-
312
+ * colon insertion) at the end of line causing errors (without semicolon.)
313
+ *
314
+ * Because it's sometimes hard to tell if a newline is part of a statement
315
+ * that should be terminated or not, we'll just leave some of them alone.
316
+ *
317
+ * @param string $content The content to strip the whitespace for
318
+ *
319
+ * @return string
320
+ */
321
+ protected function stripWhitespace($content)
322
+ {
323
+ // uniform line endings, make them all line feed
324
+ $content = str_replace(array("\r\n", "\r"), "\n", $content);
325
+
326
+ // collapse all non-line feed whitespace into a single space
327
+ $content = preg_replace('/[^\S\n]+/', ' ', $content);
328
+
329
+ // strip leading & trailing whitespace
330
+ $content = str_replace(array(" \n", "\n "), "\n", $content);
331
+
332
+ // collapse consecutive line feeds into just 1
333
+ $content = preg_replace('/\n+/', "\n", $content);
334
+
335
+ $operatorsBefore = $this->getOperatorsForRegex($this->operatorsBefore, '/');
336
+ $operatorsAfter = $this->getOperatorsForRegex($this->operatorsAfter, '/');
337
+ $operators = $this->getOperatorsForRegex($this->operators, '/');
338
+ $keywordsBefore = $this->getKeywordsForRegex($this->keywordsBefore, '/');
339
+ $keywordsAfter = $this->getKeywordsForRegex($this->keywordsAfter, '/');
340
+
341
+ // strip whitespace that ends in (or next line begin with) an operator
342
+ // that allows statements to be broken up over multiple lines
343
+ unset($operatorsBefore['+'], $operatorsBefore['-'], $operatorsAfter['+'], $operatorsAfter['-']);
344
+ $content = preg_replace(
345
+ array(
346
+ '/('.implode('|', $operatorsBefore).')\s+/',
347
+ '/\s+('.implode('|', $operatorsAfter).')/',
348
+ ),
349
+ '\\1',
350
+ $content
351
+ );
352
+
353
+ // make sure + and - can't be mistaken for, or joined into ++ and --
354
+ $content = preg_replace(
355
+ array(
356
+ '/(?<![\+\-])\s*([\+\-])(?![\+\-])/',
357
+ '/(?<![\+\-])([\+\-])\s*(?![\+\-])/',
358
+ ),
359
+ '\\1',
360
+ $content
361
+ );
362
+
363
+ // collapse whitespace around reserved words into single space
364
+ $content = preg_replace('/(^|[;\}\s])\K('.implode('|', $keywordsBefore).')\s+/', '\\2 ', $content);
365
+ $content = preg_replace('/\s+('.implode('|', $keywordsAfter).')(?=([;\{\s]|$))/', ' \\1', $content);
366
+
367
+ /*
368
+ * We didn't strip whitespace after a couple of operators because they
369
+ * could be used in different contexts and we can't be sure it's ok to
370
+ * strip the newlines. However, we can safely strip any non-line feed
371
+ * whitespace that follows them.
372
+ */
373
+ $operatorsDiffBefore = array_diff($operators, $operatorsBefore);
374
+ $operatorsDiffAfter = array_diff($operators, $operatorsAfter);
375
+ $content = preg_replace('/('.implode('|', $operatorsDiffBefore).')[^\S\n]+/', '\\1', $content);
376
+ $content = preg_replace('/[^\S\n]+('.implode('|', $operatorsDiffAfter).')/', '\\1', $content);
377
+
378
+ /*
379
+ * Whitespace after `return` can be omitted in a few occasions
380
+ * (such as when followed by a string or regex)
381
+ * Same for whitespace in between `)` and `{`, or between `{` and some
382
+ * keywords.
383
+ */
384
+ $content = preg_replace('/\breturn\s+(["\'\/\+\-])/', 'return$1', $content);
385
+ $content = preg_replace('/\)\s+\{/', '){', $content);
386
+ $content = preg_replace('/}\n(else|catch|finally)\b/', '}$1', $content);
387
+
388
+ /*
389
+ * Get rid of double semicolons, except where they can be used like:
390
+ * "for(v=1,_=b;;)", "for(v=1;;v++)" or "for(;;ja||(ja=true))".
391
+ * I'll safeguard these double semicolons inside for-loops by
392
+ * temporarily replacing them with an invalid condition: they won't have
393
+ * a double semicolon and will be easy to spot to restore afterwards.
394
+ */
395
+ $content = preg_replace('/\bfor\(([^;]*);;([^;]*)\)/', 'for(\\1;-;\\2)', $content);
396
+ $content = preg_replace('/;+/', ';', $content);
397
+ $content = preg_replace('/\bfor\(([^;]*);-;([^;]*)\)/', 'for(\\1;;\\2)', $content);
398
+
399
+ /*
400
+ * Next, we'll be removing all semicolons where ASI kicks in.
401
+ * for-loops however, can have an empty body (ending in only a
402
+ * semicolon), like: `for(i=1;i<3;i++);`, of `for(i in list);`
403
+ * Here, nothing happens during the loop; it's just used to keep
404
+ * increasing `i`. With that ; omitted, the next line would be expected
405
+ * to be the for-loop's body... Same goes for while loops.
406
+ * I'm going to double that semicolon (if any) so after the next line,
407
+ * which strips semicolons here & there, we're still left with this one.
408
+ */
409
+ $content = preg_replace('/(for\([^;\{]*;[^;\{]*;[^;\{]*\));(\}|$)/s', '\\1;;\\2', $content);
410
+ $content = preg_replace('/(for\([^;\{]+\s+in\s+[^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
411
+ /*
412
+ * Below will also keep `;` after a `do{}while();` along with `while();`
413
+ * While these could be stripped after do-while, detecting this
414
+ * distinction is cumbersome, so I'll play it safe and make sure `;`
415
+ * after any kind of `while` is kept.
416
+ */
417
+ $content = preg_replace('/(while\([^;\{]+\));(\}|$)/s', '\\1;;\\2', $content);
418
+
419
+ /*
420
+ * We also can't strip empty else-statements. Even though they're
421
+ * useless and probably shouldn't be in the code in the first place, we
422
+ * shouldn't be stripping the `;` that follows it as it breaks the code.
423
+ * We can just remove those useless else-statements completely.
424
+ *
425
+ * @see https://github.com/matthiasmullie/minify/issues/91
426
+ */
427
+ $content = preg_replace('/else;/s', '', $content);
428
+
429
+ /*
430
+ * We also don't really want to terminate statements followed by closing
431
+ * curly braces (which we've ignored completely up until now) or end-of-
432
+ * script: ASI will kick in here & we're all about minifying.
433
+ * Semicolons at beginning of the file don't make any sense either.
434
+ */
435
+ $content = preg_replace('/;(\}|$)/s', '\\1', $content);
436
+ $content = ltrim($content, ';');
437
+
438
+ // get rid of remaining whitespace af beginning/end
439
+ return trim($content);
440
+ }
441
+
442
+ /**
443
+ * We'll strip whitespace around certain operators with regular expressions.
444
+ * This will prepare the given array by escaping all characters.
445
+ *
446
+ * @param string[] $operators
447
+ * @param string $delimiter
448
+ *
449
+ * @return string[]
450
+ */
451
+ protected function getOperatorsForRegex(array $operators, $delimiter = '/')
452
+ {
453
+ // escape operators for use in regex
454
+ $delimiters = array_fill(0, count($operators), $delimiter);
455
+ $escaped = array_map('preg_quote', $operators, $delimiters);
456
+
457
+ $operators = array_combine($operators, $escaped);
458
+
459
+ // ignore + & - for now, they'll get special treatment
460
+ unset($operators['+'], $operators['-']);
461
+
462
+ // dot can not just immediately follow a number; it can be confused for
463
+ // decimal point, or calling a method on it, e.g. 42 .toString()
464
+ $operators['.'] = '(?<![0-9]\s)\.';
465
+
466
+ // don't confuse = with other assignment shortcuts (e.g. +=)
467
+ $chars = preg_quote('+-*\=<>%&|', $delimiter);
468
+ $operators['='] = '(?<!['.$chars.'])\=';
469
+
470
+ return $operators;
471
+ }
472
+
473
+ /**
474
+ * We'll strip whitespace around certain keywords with regular expressions.
475
+ * This will prepare the given array by escaping all characters.
476
+ *
477
+ * @param string[] $keywords
478
+ * @param string $delimiter
479
+ *
480
+ * @return string[]
481
+ */
482
+ protected function getKeywordsForRegex(array $keywords, $delimiter = '/')
483
+ {
484
+ // escape keywords for use in regex
485
+ $delimiter = array_fill(0, count($keywords), $delimiter);
486
+ $escaped = array_map('preg_quote', $keywords, $delimiter);
487
+
488
+ // add word boundaries
489
+ array_walk($keywords, function ($value) {
490
+ return '\b'.$value.'\b';
491
+ });
492
+
493
+ $keywords = array_combine($keywords, $escaped);
494
+
495
+ return $keywords;
496
+ }
497
+
498
+ /**
499
+ * Replaces all occurrences of array['key'] by array.key.
500
+ *
501
+ * @param string $content
502
+ *
503
+ * @return string
504
+ */
505
+ protected function propertyNotation($content)
506
+ {
507
+ // PHP only supports $this inside anonymous functions since 5.4
508
+ $minifier = $this;
509
+ $keywords = $this->keywordsReserved;
510
+ $callback = function ($match) use ($minifier, $keywords) {
511
+ $property = trim($minifier->extracted[$match[1]], '\'"');
512
+
513
+ /*
514
+ * Check if the property is a reserved keyword. In this context (as
515
+ * property of an object literal/array) it shouldn't matter, but IE8
516
+ * freaks out with "Expected identifier".
517
+ */
518
+ if (in_array($property, $keywords)) {
519
+ return $match[0];
520
+ }
521
+
522
+ /*
523
+ * See if the property is in a variable-like format (e.g.
524
+ * array['key-here'] can't be replaced by array.key-here since '-'
525
+ * is not a valid character there.
526
+ */
527
+ if (!preg_match('/^'.$minifier::REGEX_VARIABLE.'$/u', $property)) {
528
+ return $match[0];
529
+ }
530
+
531
+ return '.'.$property;
532
+ };
533
+
534
+ /*
535
+ * Figure out if previous character is a variable name (of the array
536
+ * we want to use property notation on) - this is to make sure
537
+ * standalone ['value'] arrays aren't confused for keys-of-an-array.
538
+ * We can (and only have to) check the last character, because PHP's
539
+ * regex implementation doesn't allow unfixed-length look-behind
540
+ * assertions.
541
+ */
542
+ preg_match('/(\[[^\]]+\])[^\]]*$/', static::REGEX_VARIABLE, $previousChar);
543
+ $previousChar = $previousChar[1];
544
+
545
+ /*
546
+ * Make sure word preceding the ['value'] is not a keyword, e.g.
547
+ * return['x']. Because -again- PHP's regex implementation doesn't allow
548
+ * unfixed-length look-behind assertions, I'm just going to do a lot of
549
+ * separate look-behind assertions, one for each keyword.
550
+ */
551
+ $keywords = $this->getKeywordsForRegex($keywords);
552
+ $keywords = '(?<!'.implode(')(?<!', $keywords).')';
553
+
554
+ return preg_replace_callback('/(?<='.$previousChar.'|\])'.$keywords.'\[\s*(([\'"])[0-9]+\\2)\s*\]/u', $callback, $content);
555
+ }
556
+
557
+ /**
558
+ * Replaces true & false by !0 and !1.
559
+ *
560
+ * @param string $content
561
+ *
562
+ * @return string
563
+ */
564
+ protected function shortenBools($content)
565
+ {
566
+ /*
567
+ * 'true' or 'false' could be used as property names (which may be
568
+ * followed by whitespace) - we must not replace those!
569
+ * Since PHP doesn't allow variable-length (to account for the
570
+ * whitespace) lookbehind assertions, I need to capture the leading
571
+ * character and check if it's a `.`
572
+ */
573
+ $callback = function ($match) {
574
+ if (trim($match[1]) === '.') {
575
+ return $match[0];
576
+ }
577
+
578
+ return $match[1].($match[2] === 'true' ? '!0' : '!1');
579
+ };
580
+ $content = preg_replace_callback('/(^|.\s*)\b(true|false)\b(?!:)/', $callback, $content);
581
+
582
+ // for(;;) is exactly the same as while(true), but shorter :)
583
+ $content = preg_replace('/\bwhile\(!0\){/', 'for(;;){', $content);
584
+
585
+ // now make sure we didn't turn any do ... while(true) into do ... for(;;)
586
+ preg_match_all('/\bdo\b/', $content, $dos, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
587
+
588
+ // go backward to make sure positional offsets aren't altered when $content changes
589
+ $dos = array_reverse($dos);
590
+ foreach ($dos as $do) {
591
+ $offsetDo = $do[0][1];
592
+
593
+ // find all `while` (now `for`) following `do`: one of those must be
594
+ // associated with the `do` and be turned back into `while`
595
+ preg_match_all('/\bfor\(;;\)/', $content, $whiles, PREG_OFFSET_CAPTURE | PREG_SET_ORDER, $offsetDo);
596
+ foreach ($whiles as $while) {
597
+ $offsetWhile = $while[0][1];
598
+
599
+ $open = substr_count($content, '{', $offsetDo, $offsetWhile - $offsetDo);
600
+ $close = substr_count($content, '}', $offsetDo, $offsetWhile - $offsetDo);
601
+ if ($open === $close) {
602
+ // only restore `while` if amount of `{` and `}` are the same;
603
+ // otherwise, that `for` isn't associated with this `do`
604
+ $content = substr_replace($content, 'while(!0)', $offsetWhile, strlen('for(;;)'));
605
+ break;
606
+ }
607
+ }
608
+ }
609
+
610
+ return $content;
611
+ }
612
+ }
vendor/minifier/minify/src/Minify.php CHANGED
@@ -1,497 +1,501 @@
1
- <?php
2
- /**
3
- * Abstract minifier class
4
- *
5
- * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
- *
7
- * @author Matthias Mullie <minify@mullie.eu>
8
- * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
- * @license MIT License
10
- */
11
- namespace MatthiasMullie\Minify;
12
-
13
- use MatthiasMullie\Minify\Exceptions\IOException;
14
- use Psr\Cache\CacheItemInterface;
15
-
16
- /**
17
- * Abstract minifier class.
18
- *
19
- * Please report bugs on https://github.com/matthiasmullie/minify/issues
20
- *
21
- * @package Minify
22
- * @author Matthias Mullie <minify@mullie.eu>
23
- * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
24
- * @license MIT License
25
- */
26
- abstract class Minify
27
- {
28
- /**
29
- * The data to be minified.
30
- *
31
- * @var string[]
32
- */
33
- protected $data = array();
34
-
35
- /**
36
- * Array of patterns to match.
37
- *
38
- * @var string[]
39
- */
40
- protected $patterns = array();
41
-
42
- /**
43
- * This array will hold content of strings and regular expressions that have
44
- * been extracted from the JS source code, so we can reliably match "code",
45
- * without having to worry about potential "code-like" characters inside.
46
- *
47
- * @var string[]
48
- */
49
- public $extracted = array();
50
-
51
- /**
52
- * Init the minify class - optionally, code may be passed along already.
53
- */
54
- public function __construct(/* $data = null, ... */)
55
- {
56
- // it's possible to add the source through the constructor as well ;)
57
- if (func_num_args()) {
58
- call_user_func_array(array($this, 'add'), func_get_args());
59
- }
60
- }
61
-
62
- /**
63
- * Add a file or straight-up code to be minified.
64
- *
65
- * @param string|string[] $data
66
- *
67
- * @return static
68
- */
69
- public function add($data /* $data = null, ... */)
70
- {
71
- // bogus "usage" of parameter $data: scrutinizer warns this variable is
72
- // not used (we're using func_get_args instead to support overloading),
73
- // but it still needs to be defined because it makes no sense to have
74
- // this function without argument :)
75
- $args = array($data) + func_get_args();
76
-
77
- // this method can be overloaded
78
- foreach ($args as $data) {
79
- if (is_array($data)) {
80
- call_user_func_array(array($this, 'add'), $data);
81
- continue;
82
- }
83
-
84
- // redefine var
85
- $data = (string) $data;
86
-
87
- // load data
88
- $value = $this->load($data);
89
- $key = ($data != $value) ? $data : count($this->data);
90
-
91
- // replace CR linefeeds etc.
92
- // @see https://github.com/matthiasmullie/minify/pull/139
93
- $value = str_replace(array("\r\n", "\r"), "\n", $value);
94
-
95
- // store data
96
- $this->data[$key] = $value;
97
- }
98
-
99
- return $this;
100
- }
101
-
102
- /**
103
- * Add a file to be minified.
104
- *
105
- * @param string|string[] $data
106
- *
107
- * @return static
108
- *
109
- * @throws IOException
110
- */
111
- public function addFile($data /* $data = null, ... */)
112
- {
113
- // bogus "usage" of parameter $data: scrutinizer warns this variable is
114
- // not used (we're using func_get_args instead to support overloading),
115
- // but it still needs to be defined because it makes no sense to have
116
- // this function without argument :)
117
- $args = array($data) + func_get_args();
118
-
119
- // this method can be overloaded
120
- foreach ($args as $path) {
121
- if (is_array($path)) {
122
- call_user_func_array(array($this, 'addFile'), $path);
123
- continue;
124
- }
125
-
126
- // redefine var
127
- $path = (string) $path;
128
-
129
- // check if we can read the file
130
- if (!$this->canImportFile($path)) {
131
- throw new IOException('The file "'.$path.'" could not be opened for reading. Check if PHP has enough permissions.');
132
- }
133
-
134
- $this->add($path);
135
- }
136
-
137
- return $this;
138
- }
139
-
140
- /**
141
- * Minify the data & (optionally) saves it to a file.
142
- *
143
- * @param string[optional] $path Path to write the data to
144
- *
145
- * @return string The minified data
146
- */
147
- public function minify($path = null)
148
- {
149
- $content = $this->execute($path);
150
-
151
- // save to path
152
- if ($path !== null) {
153
- $this->save($content, $path);
154
- }
155
-
156
- return $content;
157
- }
158
-
159
- /**
160
- * Minify & gzip the data & (optionally) saves it to a file.
161
- *
162
- * @param string[optional] $path Path to write the data to
163
- * @param int[optional] $level Compression level, from 0 to 9
164
- *
165
- * @return string The minified & gzipped data
166
- */
167
- public function gzip($path = null, $level = 9)
168
- {
169
- $content = $this->execute($path);
170
- $content = gzencode($content, $level, FORCE_GZIP);
171
-
172
- // save to path
173
- if ($path !== null) {
174
- $this->save($content, $path);
175
- }
176
-
177
- return $content;
178
- }
179
-
180
- /**
181
- * Minify the data & write it to a CacheItemInterface object.
182
- *
183
- * @param CacheItemInterface $item Cache item to write the data to
184
- *
185
- * @return CacheItemInterface Cache item with the minifier data
186
- */
187
- public function cache(CacheItemInterface $item)
188
- {
189
- $content = $this->execute();
190
- $item->set($content);
191
-
192
- return $item;
193
- }
194
-
195
- /**
196
- * Minify the data.
197
- *
198
- * @param string[optional] $path Path to write the data to
199
- *
200
- * @return string The minified data
201
- */
202
- abstract public function execute($path = null);
203
-
204
- /**
205
- * Load data.
206
- *
207
- * @param string $data Either a path to a file or the content itself
208
- *
209
- * @return string
210
- */
211
- protected function load($data)
212
- {
213
- // check if the data is a file
214
- if ($this->canImportFile($data)) {
215
- $data = file_get_contents($data);
216
-
217
- // strip BOM, if any
218
- if (substr($data, 0, 3) == "\xef\xbb\xbf") {
219
- $data = substr($data, 3);
220
- }
221
- }
222
-
223
- return $data;
224
- }
225
-
226
- /**
227
- * Save to file.
228
- *
229
- * @param string $content The minified data
230
- * @param string $path The path to save the minified data to
231
- *
232
- * @throws IOException
233
- */
234
- protected function save($content, $path)
235
- {
236
- $handler = $this->openFileForWriting($path);
237
-
238
- $this->writeToFile($handler, $content);
239
-
240
- @fclose($handler);
241
- }
242
-
243
- /**
244
- * Register a pattern to execute against the source content.
245
- *
246
- * @param string $pattern PCRE pattern
247
- * @param string|callable $replacement Replacement value for matched pattern
248
- */
249
- protected function registerPattern($pattern, $replacement = '')
250
- {
251
- // study the pattern, we'll execute it more than once
252
- $pattern .= 'S';
253
-
254
- $this->patterns[] = array($pattern, $replacement);
255
- }
256
-
257
- /**
258
- * We can't "just" run some regular expressions against JavaScript: it's a
259
- * complex language. E.g. having an occurrence of // xyz would be a comment,
260
- * unless it's used within a string. Of you could have something that looks
261
- * like a 'string', but inside a comment.
262
- * The only way to accurately replace these pieces is to traverse the JS one
263
- * character at a time and try to find whatever starts first.
264
- *
265
- * @param string $content The content to replace patterns in
266
- *
267
- * @return string The (manipulated) content
268
- */
269
- protected function replace($content)
270
- {
271
- $processed = '';
272
- $positions = array_fill(0, count($this->patterns), -1);
273
- $matches = array();
274
-
275
- while ($content) {
276
- // find first match for all patterns
277
- foreach ($this->patterns as $i => $pattern) {
278
- list($pattern, $replacement) = $pattern;
279
-
280
- // we can safely ignore patterns for positions we've unset earlier,
281
- // because we know these won't show up anymore
282
- if (array_key_exists($i, $positions) == false) {
283
- continue;
284
- }
285
-
286
- // no need to re-run matches that are still in the part of the
287
- // content that hasn't been processed
288
- if ($positions[$i] >= 0) {
289
- continue;
290
- }
291
-
292
- $match = null;
293
- if (preg_match($pattern, $content, $match, PREG_OFFSET_CAPTURE)) {
294
- $matches[$i] = $match;
295
-
296
- // we'll store the match position as well; that way, we
297
- // don't have to redo all preg_matches after changing only
298
- // the first (we'll still know where those others are)
299
- $positions[$i] = $match[0][1];
300
- } else {
301
- // if the pattern couldn't be matched, there's no point in
302
- // executing it again in later runs on this same content;
303
- // ignore this one until we reach end of content
304
- unset($matches[$i], $positions[$i]);
305
- }
306
- }
307
-
308
- // no more matches to find: everything's been processed, break out
309
- if (!$matches) {
310
- $processed .= $content;
311
- break;
312
- }
313
-
314
- // see which of the patterns actually found the first thing (we'll
315
- // only want to execute that one, since we're unsure if what the
316
- // other found was not inside what the first found)
317
- $discardLength = min($positions);
318
- $firstPattern = array_search($discardLength, $positions);
319
- $match = $matches[$firstPattern][0][0];
320
-
321
- // execute the pattern that matches earliest in the content string
322
- list($pattern, $replacement) = $this->patterns[$firstPattern];
323
- $replacement = $this->replacePattern($pattern, $replacement, $content);
324
-
325
- // figure out which part of the string was unmatched; that's the
326
- // part we'll execute the patterns on again next
327
- $content = (string) substr($content, $discardLength);
328
- $unmatched = (string) substr($content, strpos($content, $match) + strlen($match));
329
-
330
- // move the replaced part to $processed and prepare $content to
331
- // again match batch of patterns against
332
- $processed .= substr($replacement, 0, strlen($replacement) - strlen($unmatched));
333
- $content = $unmatched;
334
-
335
- // first match has been replaced & that content is to be left alone,
336
- // the next matches will start after this replacement, so we should
337
- // fix their offsets
338
- foreach ($positions as $i => $position) {
339
- $positions[$i] -= $discardLength + strlen($match);
340
- }
341
- }
342
-
343
- return $processed;
344
- }
345
-
346
- /**
347
- * This is where a pattern is matched against $content and the matches
348
- * are replaced by their respective value.
349
- * This function will be called plenty of times, where $content will always
350
- * move up 1 character.
351
- *
352
- * @param string $pattern Pattern to match
353
- * @param string|callable $replacement Replacement value
354
- * @param string $content Content to match pattern against
355
- *
356
- * @return string
357
- */
358
- protected function replacePattern($pattern, $replacement, $content)
359
- {
360
- if (is_callable($replacement)) {
361
- return preg_replace_callback($pattern, $replacement, $content, 1, $count);
362
- } else {
363
- return preg_replace($pattern, $replacement, $content, 1, $count);
364
- }
365
- }
366
-
367
- /**
368
- * Strings are a pattern we need to match, in order to ignore potential
369
- * code-like content inside them, but we just want all of the string
370
- * content to remain untouched.
371
- *
372
- * This method will replace all string content with simple STRING#
373
- * placeholder text, so we've rid all strings from characters that may be
374
- * misinterpreted. Original string content will be saved in $this->extracted
375
- * and after doing all other minifying, we can restore the original content
376
- * via restoreStrings().
377
- *
378
- * @param string[optional] $chars
379
- * @param string[optional] $placeholderPrefix
380
- */
381
- protected function extractStrings($chars = '\'"', $placeholderPrefix = '')
382
- {
383
- // PHP only supports $this inside anonymous functions since 5.4
384
- $minifier = $this;
385
- $callback = function ($match) use ($minifier, $placeholderPrefix) {
386
- // check the second index here, because the first always contains a quote
387
- if ($match[2] === '') {
388
- /*
389
- * Empty strings need no placeholder; they can't be confused for
390
- * anything else anyway.
391
- * But we still needed to match them, for the extraction routine
392
- * to skip over this particular string.
393
- */
394
- return $match[0];
395
- }
396
-
397
- $count = count($minifier->extracted);
398
- $placeholder = $match[1].$placeholderPrefix.$count.$match[1];
399
- $minifier->extracted[$placeholder] = $match[1].$match[2].$match[1];
400
-
401
- return $placeholder;
402
- };
403
-
404
- /*
405
- * The \\ messiness explained:
406
- * * Don't count ' or " as end-of-string if it's escaped (has backslash
407
- * in front of it)
408
- * * Unless... that backslash itself is escaped (another leading slash),
409
- * in which case it's no longer escaping the ' or "
410
- * * So there can be either no backslash, or an even number
411
- * * multiply all of that times 4, to account for the escaping that has
412
- * to be done to pass the backslash into the PHP string without it being
413
- * considered as escape-char (times 2) and to get it in the regex,
414
- * escaped (times 2)
415
- */
416
- $this->registerPattern('/(['.$chars.'])(.*?(?<!\\\\)(\\\\\\\\)*+)\\1/s', $callback);
417
- }
418
-
419
- /**
420
- * This method will restore all extracted data (strings, regexes) that were
421
- * replaced with placeholder text in extract*(). The original content was
422
- * saved in $this->extracted.
423
- *
424
- * @param string $content
425
- *
426
- * @return string
427
- */
428
- protected function restoreExtractedData($content)
429
- {
430
- if (!$this->extracted) {
431
- // nothing was extracted, nothing to restore
432
- return $content;
433
- }
434
-
435
- $content = strtr($content, $this->extracted);
436
-
437
- $this->extracted = array();
438
-
439
- return $content;
440
- }
441
-
442
- /**
443
- * Check if the path is a regular file and can be read.
444
- *
445
- * @param string $path
446
- *
447
- * @return bool
448
- */
449
- protected function canImportFile($path)
450
- {
451
- $parsed = parse_url($path);
452
- if (
453
- // file is elsewhere
454
- isset($parsed['host']) ||
455
- // file responds to queries (may change, or need to bypass cache)
456
- isset($parsed['query'])
457
- ) {
458
- return false;
459
- }
460
-
461
- return strlen($path) < PHP_MAXPATHLEN && @is_file($path) && is_readable($path);
462
- }
463
-
464
- /**
465
- * Attempts to open file specified by $path for writing.
466
- *
467
- * @param string $path The path to the file
468
- *
469
- * @return resource Specifier for the target file
470
- *
471
- * @throws IOException
472
- */
473
- protected function openFileForWriting($path)
474
- {
475
- if (($handler = @fopen($path, 'w')) === false) {
476
- throw new IOException('The file "'.$path.'" could not be opened for writing. Check if PHP has enough permissions.');
477
- }
478
-
479
- return $handler;
480
- }
481
-
482
- /**
483
- * Attempts to write $content to the file specified by $handler. $path is used for printing exceptions.
484
- *
485
- * @param resource $handler The resource to write to
486
- * @param string $content The content to write
487
- * @param string $path The path to the file (for exception printing only)
488
- *
489
- * @throws IOException
490
- */
491
- protected function writeToFile($handler, $content, $path = '')
492
- {
493
- if (($result = @fwrite($handler, $content)) === false || ($result < strlen($content))) {
494
- throw new IOException('The file "'.$path.'" could not be written to. Check your disk space and file permissions.');
495
- }
496
- }
497
- }
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Abstract minifier class
4
+ *
5
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
6
+ *
7
+ * @author Matthias Mullie <minify@mullie.eu>
8
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
9
+ * @license MIT License
10
+ */
11
+ namespace MatthiasMullie\Minify;
12
+
13
+ use MatthiasMullie\Minify\Exceptions\IOException;
14
+ use Psr\Cache\CacheItemInterface;
15
+
16
+ /**
17
+ * Abstract minifier class.
18
+ *
19
+ * Please report bugs on https://github.com/matthiasmullie/minify/issues
20
+ *
21
+ * @package Minify
22
+ * @author Matthias Mullie <minify@mullie.eu>
23
+ * @copyright Copyright (c) 2012, Matthias Mullie. All rights reserved
24
+ * @license MIT License
25
+ */
26
+ abstract class Minify
27
+ {
28
+ /**
29
+ * The data to be minified.
30
+ *
31
+ * @var string[]
32
+ */
33
+ protected $data = array();
34
+
35
+ /**
36
+ * Array of patterns to match.
37
+ *
38
+ * @var string[]
39
+ */
40
+ protected $patterns = array();
41
+
42
+ /**
43
+ * This array will hold content of strings and regular expressions that have
44
+ * been extracted from the JS source code, so we can reliably match "code",
45
+ * without having to worry about potential "code-like" characters inside.
46
+ *
47
+ * @var string[]
48
+ */
49
+ public $extracted = array();
50
+
51
+ /**
52
+ * Init the minify class - optionally, code may be passed along already.
53
+ */
54
+ public function __construct(/* $data = null, ... */)
55
+ {
56
+ // it's possible to add the source through the constructor as well ;)
57
+ if (func_num_args()) {
58
+ call_user_func_array(array($this, 'add'), func_get_args());
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Add a file or straight-up code to be minified.
64
+ *
65
+ * @param string|string[] $data
66
+ *
67
+ * @return static
68
+ */
69
+ public function add($data /* $data = null, ... */)
70
+ {
71
+ // bogus "usage" of parameter $data: scrutinizer warns this variable is
72
+ // not used (we're using func_get_args instead to support overloading),
73
+ // but it still needs to be defined because it makes no sense to have
74
+ // this function without argument :)
75
+ $args = array($data) + func_get_args();
76
+
77
+ // this method can be overloaded
78
+ foreach ($args as $data) {
79
+ if (is_array($data)) {
80
+ call_user_func_array(array($this, 'add'), $data);
81
+ continue;
82
+ }
83
+
84
+ // redefine var
85
+ $data = (string) $data;
86
+
87
+ // load data
88
+ $value = $this->load($data);
89
+ $key = ($data != $value) ? $data : count($this->data);
90
+
91
+ // replace CR linefeeds etc.
92
+ // @see https://github.com/matthiasmullie/minify/pull/139
93
+ $value = str_replace(array("\r\n", "\r"), "\n", $value);
94
+
95
+ // store data
96
+ $this->data[$key] = $value;
97
+ }
98
+
99
+ return $this;
100
+ }
101
+
102
+ /**
103
+ * Add a file to be minified.
104
+ *
105
+ * @param string|string[] $data
106
+ *
107
+ * @return static
108
+ *
109
+ * @throws IOException
110
+ */
111
+ public function addFile($data /* $data = null, ... */)
112
+ {
113
+ // bogus "usage" of parameter $data: scrutinizer warns this variable is
114
+ // not used (we're using func_get_args instead to support overloading),
115
+ // but it still needs to be defined because it makes no sense to have
116
+ // this function without argument :)
117
+ $args = array($data) + func_get_args();
118
+
119
+ // this method can be overloaded
120
+ foreach ($args as $path) {
121
+ if (is_array($path)) {
122
+ call_user_func_array(array($this, 'addFile'), $path);
123
+ continue;
124
+ }
125
+
126
+ // redefine var
127
+ $path = (string) $path;
128
+
129
+ // check if we can read the file
130
+ if (!$this->canImportFile($path)) {
131
+ throw new IOException('The file "'.$path.'" could not be opened for reading. Check if PHP has enough permissions.');
132
+ }
133
+
134
+ $this->add($path);
135
+ }
136
+
137
+ return $this;
138
+ }
139
+
140
+ /**
141
+ * Minify the data & (optionally) saves it to a file.
142
+ *
143
+ * @param string[optional] $path Path to write the data to
144
+ *
145
+ * @return string The minified data
146
+ */
147
+ public function minify($path = null)
148
+ {
149
+ $content = $this->execute($path);
150
+
151
+ // save to path
152
+ if ($path !== null) {
153
+ $this->save($content, $path);
154
+ }
155
+
156
+ return $content;
157
+ }
158
+
159
+ /**
160
+ * Minify & gzip the data & (optionally) saves it to a file.
161
+ *
162
+ * @param string[optional] $path Path to write the data to
163
+ * @param int[optional] $level Compression level, from 0 to 9
164
+ *
165
+ * @return string The minified & gzipped data
166
+ */
167
+ public function gzip($path = null, $level = 9)
168
+ {
169
+ $content = $this->execute($path);
170
+ $content = gzencode($content, $level, FORCE_GZIP);
171
+
172
+ // save to path
173
+ if ($path !== null) {
174
+ $this->save($content, $path);
175
+ }
176
+
177
+ return $content;
178
+ }
179
+
180
+ /**
181
+ * Minify the data & write it to a CacheItemInterface object.
182
+ *
183
+ * @param CacheItemInterface $item Cache item to write the data to
184
+ *
185
+ * @return CacheItemInterface Cache item with the minifier data
186
+ */
187
+ public function cache(CacheItemInterface $item)
188
+ {
189
+ $content = $this->execute();
190
+ $item->set($content);
191
+
192
+ return $item;
193
+ }
194
+
195
+ /**
196
+ * Minify the data.
197
+ *
198
+ * @param string[optional] $path Path to write the data to
199
+ *
200
+ * @return string The minified data
201
+ */
202
+ abstract public function execute($path = null);
203
+
204
+ /**
205
+ * Load data.
206
+ *
207
+ * @param string $data Either a path to a file or the content itself
208
+ *
209
+ * @return string
210
+ */
211
+ protected function load($data)
212
+ {
213
+ // check if the data is a file
214
+ if ($this->canImportFile($data)) {
215
+ $data = file_get_contents($data);
216
+
217
+ // strip BOM, if any
218
+ if (substr($data, 0, 3) == "\xef\xbb\xbf") {
219
+ $data = substr($data, 3);
220
+ }
221
+ }
222
+
223
+ return $data;
224
+ }
225
+
226
+ /**
227
+ * Save to file.
228
+ *
229
+ * @param string $content The minified data
230
+ * @param string $path The path to save the minified data to
231
+ *
232
+ * @throws IOException
233
+ */
234
+ protected function save($content, $path)
235
+ {
236
+ $handler = $this->openFileForWriting($path);
237
+
238
+ $this->writeToFile($handler, $content);
239
+
240
+ @fclose($handler);
241
+ }
242
+
243
+ /**
244
+ * Register a pattern to execute against the source content.
245
+ *
246
+ * @param string $pattern PCRE pattern
247
+ * @param string|callable $replacement Replacement value for matched pattern
248
+ */
249
+ protected function registerPattern($pattern, $replacement = '')
250
+ {
251
+ // study the pattern, we'll execute it more than once
252
+ $pattern .= 'S';
253
+
254
+ $this->patterns[] = array($pattern, $replacement);
255
+ }
256
+
257
+ /**
258
+ * We can't "just" run some regular expressions against JavaScript: it's a
259
+ * complex language. E.g. having an occurrence of // xyz would be a comment,
260
+ * unless it's used within a string. Of you could have something that looks
261
+ * like a 'string', but inside a comment.
262
+ * The only way to accurately replace these pieces is to traverse the JS one
263
+ * character at a time and try to find whatever starts first.
264
+ *
265
+ * @param string $content The content to replace patterns in
266
+ *
267
+ * @return string The (manipulated) content
268
+ */
269
+ protected function replace($content)
270
+ {
271
+ $processed = '';
272
+ $positions = array_fill(0, count($this->patterns), -1);
273
+ $matches = array();
274
+
275
+ while ($content) {
276
+ // find first match for all patterns
277
+ foreach ($this->patterns as $i => $pattern) {
278
+ list($pattern, $replacement) = $pattern;
279
+
280
+ // we can safely ignore patterns for positions we've unset earlier,
281
+ // because we know these won't show up anymore
282
+ if (array_key_exists($i, $positions) == false) {
283
+ continue;
284
+ }
285
+
286
+ // no need to re-run matches that are still in the part of the
287
+ // content that hasn't been processed
288
+ if ($positions[$i] >= 0) {
289
+ continue;
290
+ }
291
+
292
+ $match = null;
293
+ if (preg_match($pattern, $content, $match, PREG_OFFSET_CAPTURE)) {
294
+ $matches[$i] = $match;
295
+
296
+ // we'll store the match position as well; that way, we
297
+ // don't have to redo all preg_matches after changing only
298
+ // the first (we'll still know where those others are)
299
+ $positions[$i] = $match[0][1];
300
+ } else {
301
+ // if the pattern couldn't be matched, there's no point in
302
+ // executing it again in later runs on this same content;
303
+ // ignore this one until we reach end of content
304
+ unset($matches[$i], $positions[$i]);
305
+ }
306
+ }
307
+
308
+ // no more matches to find: everything's been processed, break out
309
+ if (!$matches) {
310
+ $processed .= $content;
311
+ break;
312
+ }
313
+
314
+ // see which of the patterns actually found the first thing (we'll
315
+ // only want to execute that one, since we're unsure if what the
316
+ // other found was not inside what the first found)
317
+ $discardLength = min($positions);
318
+ $firstPattern = array_search($discardLength, $positions);
319
+ $match = $matches[$firstPattern][0][0];
320
+
321
+ // execute the pattern that matches earliest in the content string
322
+ list($pattern, $replacement) = $this->patterns[$firstPattern];
323
+ $replacement = $this->replacePattern($pattern, $replacement, $content);
324
+
325
+ // figure out which part of the string was unmatched; that's the
326
+ // part we'll execute the patterns on again next
327
+ $content = (string) substr($content, $discardLength);
328
+ $unmatched = (string) substr($content, strpos($content, $match) + strlen($match));
329
+
330
+ // move the replaced part to $processed and prepare $content to
331
+ // again match batch of patterns against
332
+ $processed .= substr($replacement, 0, strlen($replacement) - strlen($unmatched));
333
+ $content = $unmatched;
334
+
335
+ // first match has been replaced & that content is to be left alone,
336
+ // the next matches will start after this replacement, so we should
337
+ // fix their offsets
338
+ foreach ($positions as $i => $position) {
339
+ $positions[$i] -= $discardLength + strlen($match);
340
+ }
341
+ }
342
+
343
+ return $processed;
344
+ }
345
+
346
+ /**
347
+ * This is where a pattern is matched against $content and the matches
348
+ * are replaced by their respective value.
349
+ * This function will be called plenty of times, where $content will always
350
+ * move up 1 character.
351
+ *
352
+ * @param string $pattern Pattern to match
353
+ * @param string|callable $replacement Replacement value
354
+ * @param string $content Content to match pattern against
355
+ *
356
+ * @return string
357
+ */
358
+ protected function replacePattern($pattern, $replacement, $content)
359
+ {
360
+ if (is_callable($replacement)) {
361
+ return preg_replace_callback($pattern, $replacement, $content, 1, $count);
362
+ } else {
363
+ return preg_replace($pattern, $replacement, $content, 1, $count);
364
+ }
365
+ }
366
+
367
+ /**
368
+ * Strings are a pattern we need to match, in order to ignore potential
369
+ * code-like content inside them, but we just want all of the string
370
+ * content to remain untouched.
371
+ *
372
+ * This method will replace all string content with simple STRING#
373
+ * placeholder text, so we've rid all strings from characters that may be
374
+ * misinterpreted. Original string content will be saved in $this->extracted
375
+ * and after doing all other minifying, we can restore the original content
376
+ * via restoreStrings().
377
+ *
378
+ * @param string[optional] $chars
379
+ * @param string[optional] $placeholderPrefix
380
+ */
381
+ protected function extractStrings($chars = '\'"', $placeholderPrefix = '')
382
+ {
383
+ // PHP only supports $this inside anonymous functions since 5.4
384
+ $minifier = $this;
385
+ $callback = function ($match) use ($minifier, $placeholderPrefix) {
386
+ // check the second index here, because the first always contains a quote
387
+ if ($match[2] === '') {
388
+ /*
389
+ * Empty strings need no placeholder; they can't be confused for
390
+ * anything else anyway.
391
+ * But we still needed to match them, for the extraction routine
392
+ * to skip over this particular string.
393
+ */
394
+ return $match[0];
395
+ }
396
+
397
+ $count = count($minifier->extracted);
398
+ $placeholder = $match[1].$placeholderPrefix.$count.$match[1];
399
+ $minifier->extracted[$placeholder] = $match[1].$match[2].$match[1];
400
+
401
+ return $placeholder;
402
+ };
403
+
404
+ /*
405
+ * The \\ messiness explained:
406
+ * * Don't count ' or " as end-of-string if it's escaped (has backslash
407
+ * in front of it)
408
+ * * Unless... that backslash itself is escaped (another leading slash),
409
+ * in which case it's no longer escaping the ' or "
410
+ * * So there can be either no backslash, or an even number
411
+ * * multiply all of that times 4, to account for the escaping that has
412
+ * to be done to pass the backslash into the PHP string without it being
413
+ * considered as escape-char (times 2) and to get it in the regex,
414
+ * escaped (times 2)
415
+ */
416
+ $this->registerPattern('/(['.$chars.'])(.*?(?<!\\\\)(\\\\\\\\)*+)\\1/s', $callback);
417
+ }
418
+
419
+ /**
420
+ * This method will restore all extracted data (strings, regexes) that were
421
+ * replaced with placeholder text in extract*(). The original content was
422
+ * saved in $this->extracted.
423
+ *
424
+ * @param string $content
425
+ *
426
+ * @return string
427
+ */
428
+ protected function restoreExtractedData($content)
429
+ {
430
+ if (!$this->extracted) {
431
+ // nothing was extracted, nothing to restore
432
+ return $content;
433
+ }
434
+
435
+ $content = strtr($content, $this->extracted);
436
+
437
+ $this->extracted = array();
438
+
439
+ return $content;
440
+ }
441
+
442
+ /**
443
+ * Check if the path is a regular file and can be read.
444
+ *
445
+ * @param string $path
446
+ *
447
+ * @return bool
448
+ */
449
+ protected function canImportFile($path)
450
+ {
451
+ $parsed = parse_url($path);
452
+ if (
453
+ // file is elsewhere
454
+ isset($parsed['host']) ||
455
+ // file responds to queries (may change, or need to bypass cache)
456
+ isset($parsed['query'])
457
+ ) {
458
+ return false;
459
+ }
460
+
461
+ return strlen($path) < PHP_MAXPATHLEN && @is_file($path) && is_readable($path);
462
+ }
463
+
464
+ /**
465
+ * Attempts to open file specified by $path for writing.
466
+ *
467
+ * @param string $path The path to the file
468
+ *
469
+ * @return resource Specifier for the target file
470
+ *
471
+ * @throws IOException
472
+ */
473
+ protected function openFileForWriting($path)
474
+ {
475
+ if ($path === '' || ($handler = @fopen($path, 'w')) === false) {
476
+ throw new IOException('The file "'.$path.'" could not be opened for writing. Check if PHP has enough permissions.');
477
+ }
478
+
479
+ return $handler;
480
+ }
481
+
482
+ /**
483
+ * Attempts to write $content to the file specified by $handler. $path is used for printing exceptions.
484
+ *
485
+ * @param resource $handler The resource to write to
486
+ * @param string $content The content to write
487
+ * @param string $path The path to the file (for exception printing only)
488
+ *
489
+ * @throws IOException
490
+ */
491
+ protected function writeToFile($handler, $content, $path = '')
492
+ {
493
+ if (
494
+ !is_resource($handler) ||
495
+ ($result = @fwrite($handler, $content)) === false ||
496
+ ($result < strlen($content))
497
+ ) {
498
+ throw new IOException('The file "'.$path.'" could not be written to. Check your disk space and file permissions.');
499
+ }
500
+ }
501
+ }
vendor/minifier/path-converter/LICENSE CHANGED
@@ -1,18 +1,18 @@
1
- Copyright (c) 2015 Matthias Mullie
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of
4
- this software and associated documentation files (the "Software"), to deal in
5
- the Software without restriction, including without limitation the rights to
6
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
- the Software, and to permit persons to whom the Software is furnished to do so,
8
- subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in all
11
- copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Copyright (c) 2015 Matthias Mullie
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
vendor/minifier/path-converter/src/Converter.php CHANGED
@@ -1,204 +1,204 @@
1
- <?php
2
-
3
- namespace MatthiasMullie\PathConverter;
4
-
5
- /**
6
- * Convert paths relative from 1 file to another.
7
- *
8
- * E.g.
9
- * ../../images/icon.jpg relative to /css/imports/icons.css
10
- * becomes
11
- * ../images/icon.jpg relative to /css/minified.css
12
- *
13
- * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
14
- *
15
- * @author Matthias Mullie <pathconverter@mullie.eu>
16
- * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
17
- * @license MIT License
18
- */
19
- class Converter implements ConverterInterface
20
- {
21
- /**
22
- * @var string
23
- */
24
- protected $from;
25
-
26
- /**
27
- * @var string
28
- */
29
- protected $to;
30
-
31
- /**
32
- * @param string $from The original base path (directory, not file!)
33
- * @param string $to The new base path (directory, not file!)
34
- * @param string $root Root directory (defaults to `getcwd`)
35
- */
36
- public function __construct($from, $to, $root = '')
37
- {
38
- $shared = $this->shared($from, $to);
39
- if ($shared === '') {
40
- // when both paths have nothing in common, one of them is probably
41
- // absolute while the other is relative
42
- $root = $root ?: getcwd();
43
- $from = strpos($from, $root) === 0 ? $from : preg_replace('/\/+/', '/', $root.'/'.$from);
44
- $to = strpos($to, $root) === 0 ? $to : preg_replace('/\/+/', '/', $root.'/'.$to);
45
-
46
- // or traveling the tree via `..`
47
- // attempt to resolve path, or assume it's fine if it doesn't exist
48
- $from = @realpath($from) ?: $from;
49
- $to = @realpath($to) ?: $to;
50
- }
51
-
52
- $from = $this->dirname($from);
53
- $to = $this->dirname($to);
54
-
55
- $from = $this->normalize($from);
56
- $to = $this->normalize($to);
57
-
58
- $this->from = $from;
59
- $this->to = $to;
60
- }
61
-
62
- /**
63
- * Normalize path.
64
- *
65
- * @param string $path
66
- *
67
- * @return string
68
- */
69
- protected function normalize($path)
70
- {
71
- // deal with different operating systems' directory structure
72
- $path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '/');
73
-
74
- // remove leading current directory.
75
- if (substr($path, 0, 2) === './') {
76
- $path = substr($path, 2);
77
- }
78
-
79
- // remove references to current directory in the path.
80
- $path = str_replace('/./', '/', $path);
81
-
82
- /*
83
- * Example:
84
- * /home/forkcms/frontend/cache/compiled_templates/../../core/layout/css/../images/img.gif
85
- * to
86
- * /home/forkcms/frontend/core/layout/images/img.gif
87
- */
88
- do {
89
- $path = preg_replace('/[^\/]+(?<!\.\.)\/\.\.\//', '', $path, -1, $count);
90
- } while ($count);
91
-
92
- return $path;
93
- }
94
-
95
- /**
96
- * Figure out the shared path of 2 locations.
97
- *
98
- * Example:
99
- * /home/forkcms/frontend/core/layout/images/img.gif
100
- * and
101
- * /home/forkcms/frontend/cache/minified_css
102
- * share
103
- * /home/forkcms/frontend
104
- *
105
- * @param string $path1
106
- * @param string $path2
107
- *
108
- * @return string
109
- */
110
- protected function shared($path1, $path2)
111
- {
112
- // $path could theoretically be empty (e.g. no path is given), in which
113
- // case it shouldn't expand to array(''), which would compare to one's
114
- // root /
115
- $path1 = $path1 ? explode('/', $path1) : array();
116
- $path2 = $path2 ? explode('/', $path2) : array();
117
-
118
- $shared = array();
119
-
120
- // compare paths & strip identical ancestors
121
- foreach ($path1 as $i => $chunk) {
122
- if (isset($path2[$i]) && $path1[$i] == $path2[$i]) {
123
- $shared[] = $chunk;
124
- } else {
125
- break;
126
- }
127
- }
128
-
129
- return implode('/', $shared);
130
- }
131
-
132
- /**
133
- * Convert paths relative from 1 file to another.
134
- *
135
- * E.g.
136
- * ../images/img.gif relative to /home/forkcms/frontend/core/layout/css
137
- * should become:
138
- * ../../core/layout/images/img.gif relative to
139
- * /home/forkcms/frontend/cache/minified_css
140
- *
141
- * @param string $path The relative path that needs to be converted
142
- *
143
- * @return string The new relative path
144
- */
145
- public function convert($path)
146
- {
147
- // quit early if conversion makes no sense
148
- if ($this->from === $this->to) {
149
- return $path;
150
- }
151
-
152
- $path = $this->normalize($path);
153
- // if we're not dealing with a relative path, just return absolute
154
- if (strpos($path, '/') === 0) {
155
- return $path;
156
- }
157
-
158
- // normalize paths
159
- $path = $this->normalize($this->from.'/'.$path);
160
-
161
- // strip shared ancestor paths
162
- $shared = $this->shared($path, $this->to);
163
- $path = mb_substr($path, mb_strlen($shared));
164
- $to = mb_substr($this->to, mb_strlen($shared));
165
-
166
- // add .. for every directory that needs to be traversed to new path
167
- $to = str_repeat('../', count(array_filter(explode('/', $to))));
168
-
169
- return $to.ltrim($path, '/');
170
- }
171
-
172
- /**
173
- * Attempt to get the directory name from a path.
174
- *
175
- * @param string $path
176
- *
177
- * @return string
178
- */
179
- protected function dirname($path)
180
- {
181
- if (@is_file($path)) {
182
- return dirname($path);
183
- }
184
-
185
- if (@is_dir($path)) {
186
- return rtrim($path, '/');
187
- }
188
-
189
- // no known file/dir, start making assumptions
190
-
191
- // ends in / = dir
192
- if (mb_substr($path, -1) === '/') {
193
- return rtrim($path, '/');
194
- }
195
-
196
- // has a dot in the name, likely a file
197
- if (preg_match('/.*\..*$/', basename($path)) !== 0) {
198
- return dirname($path);
199
- }
200
-
201
- // you're on your own here!
202
- return $path;
203
- }
204
- }
1
+ <?php
2
+
3
+ namespace MatthiasMullie\PathConverter;
4
+
5
+ /**
6
+ * Convert paths relative from 1 file to another.
7
+ *
8
+ * E.g.
9
+ * ../../images/icon.jpg relative to /css/imports/icons.css
10
+ * becomes
11
+ * ../images/icon.jpg relative to /css/minified.css
12
+ *
13
+ * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
14
+ *
15
+ * @author Matthias Mullie <pathconverter@mullie.eu>
16
+ * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
17
+ * @license MIT License
18
+ */
19
+ class Converter implements ConverterInterface
20
+ {
21
+ /**
22
+ * @var string
23
+ */
24
+ protected $from;
25
+
26
+ /**
27
+ * @var string
28
+ */
29
+ protected $to;
30
+
31
+ /**
32
+ * @param string $from The original base path (directory, not file!)
33
+ * @param string $to The new base path (directory, not file!)
34
+ * @param string $root Root directory (defaults to `getcwd`)
35
+ */
36
+ public function __construct($from, $to, $root = '')
37
+ {
38
+ $shared = $this->shared($from, $to);
39
+ if ($shared === '') {
40
+ // when both paths have nothing in common, one of them is probably
41
+ // absolute while the other is relative
42
+ $root = $root ?: getcwd();
43
+ $from = strpos($from, $root) === 0 ? $from : preg_replace('/\/+/', '/', $root.'/'.$from);
44
+ $to = strpos($to, $root) === 0 ? $to : preg_replace('/\/+/', '/', $root.'/'.$to);
45
+
46
+ // or traveling the tree via `..`
47
+ // attempt to resolve path, or assume it's fine if it doesn't exist
48
+ $from = @realpath($from) ?: $from;
49
+ $to = @realpath($to) ?: $to;
50
+ }
51
+
52
+ $from = $this->dirname($from);
53
+ $to = $this->dirname($to);
54
+
55
+ $from = $this->normalize($from);
56
+ $to = $this->normalize($to);
57
+
58
+ $this->from = $from;
59
+ $this->to = $to;
60
+ }
61
+
62
+ /**
63
+ * Normalize path.
64
+ *
65
+ * @param string $path
66
+ *
67
+ * @return string
68
+ */
69
+ protected function normalize($path)
70
+ {
71
+ // deal with different operating systems' directory structure
72
+ $path = rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '/');
73
+
74
+ // remove leading current directory.
75
+ if (substr($path, 0, 2) === './') {
76
+ $path = substr($path, 2);
77
+ }
78
+
79
+ // remove references to current directory in the path.
80
+ $path = str_replace('/./', '/', $path);
81
+
82
+ /*
83
+ * Example:
84
+ * /home/forkcms/frontend/cache/compiled_templates/../../core/layout/css/../images/img.gif
85
+ * to
86
+ * /home/forkcms/frontend/core/layout/images/img.gif
87
+ */
88
+ do {
89
+ $path = preg_replace('/[^\/]+(?<!\.\.)\/\.\.\//', '', $path, -1, $count);
90
+ } while ($count);
91
+
92
+ return $path;
93
+ }
94
+
95
+ /**
96
+ * Figure out the shared path of 2 locations.
97
+ *
98
+ * Example:
99
+ * /home/forkcms/frontend/core/layout/images/img.gif
100
+ * and
101
+ * /home/forkcms/frontend/cache/minified_css
102
+ * share
103
+ * /home/forkcms/frontend
104
+ *
105
+ * @param string $path1
106
+ * @param string $path2
107
+ *
108
+ * @return string
109
+ */
110
+ protected function shared($path1, $path2)
111
+ {
112
+ // $path could theoretically be empty (e.g. no path is given), in which
113
+ // case it shouldn't expand to array(''), which would compare to one's
114
+ // root /
115
+ $path1 = $path1 ? explode('/', $path1) : array();
116
+ $path2 = $path2 ? explode('/', $path2) : array();
117
+
118
+ $shared = array();
119
+
120
+ // compare paths & strip identical ancestors
121
+ foreach ($path1 as $i => $chunk) {
122
+ if (isset($path2[$i]) && $path1[$i] == $path2[$i]) {
123
+ $shared[] = $chunk;
124
+ } else {
125
+ break;
126
+ }
127
+ }
128
+
129
+ return implode('/', $shared);
130
+ }
131
+
132
+ /**
133
+ * Convert paths relative from 1 file to another.
134
+ *
135
+ * E.g.
136
+ * ../images/img.gif relative to /home/forkcms/frontend/core/layout/css
137
+ * should become:
138
+ * ../../core/layout/images/img.gif relative to
139
+ * /home/forkcms/frontend/cache/minified_css
140
+ *
141
+ * @param string $path The relative path that needs to be converted
142
+ *
143
+ * @return string The new relative path
144
+ */
145
+ public function convert($path)
146
+ {
147
+ // quit early if conversion makes no sense
148
+ if ($this->from === $this->to) {
149
+ return $path;
150
+ }
151
+
152
+ $path = $this->normalize($path);
153
+ // if we're not dealing with a relative path, just return absolute
154
+ if (strpos($path, '/') === 0) {
155
+ return $path;
156
+ }
157
+
158
+ // normalize paths
159
+ $path = $this->normalize($this->from.'/'.$path);
160
+
161
+ // strip shared ancestor paths
162
+ $shared = $this->shared($path, $this->to);
163
+ $path = mb_substr($path, mb_strlen($shared));
164
+ $to = mb_substr($this->to, mb_strlen($shared));
165
+
166
+ // add .. for every directory that needs to be traversed to new path
167
+ $to = str_repeat('../', count(array_filter(explode('/', $to))));
168
+
169
+ return $to.ltrim($path, '/');
170
+ }
171
+
172
+ /**
173
+ * Attempt to get the directory name from a path.
174
+ *
175
+ * @param string $path
176
+ *
177
+ * @return string
178
+ */
179
+ protected function dirname($path)
180
+ {
181
+ if (@is_file($path)) {
182
+ return dirname($path);
183
+ }
184
+
185
+ if (@is_dir($path)) {
186
+ return rtrim($path, '/');
187
+ }
188
+
189
+ // no known file/dir, start making assumptions
190
+
191
+ // ends in / = dir
192
+ if (mb_substr($path, -1) === '/') {
193
+ return rtrim($path, '/');
194
+ }
195
+
196
+ // has a dot in the name, likely a file
197
+ if (preg_match('/.*\..*$/', basename($path)) !== 0) {
198
+ return dirname($path);
199
+ }
200
+
201
+ // you're on your own here!
202
+ return $path;
203
+ }
204
+ }
vendor/minifier/path-converter/src/ConverterInterface.php CHANGED
@@ -1,24 +1,24 @@
1
- <?php
2
-
3
- namespace MatthiasMullie\PathConverter;
4
-
5
- /**
6
- * Convert file paths.
7
- *
8
- * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
9
- *
10
- * @author Matthias Mullie <pathconverter@mullie.eu>
11
- * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
12
- * @license MIT License
13
- */
14
- interface ConverterInterface
15
- {
16
- /**
17
- * Convert file paths.
18
- *
19
- * @param string $path The path to be converted
20
- *
21
- * @return string The new path
22
- */
23
- public function convert($path);
24
- }
1
+ <?php
2
+
3
+ namespace MatthiasMullie\PathConverter;
4
+
5
+ /**
6
+ * Convert file paths.
7
+ *
8
+ * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
9
+ *
10
+ * @author Matthias Mullie <pathconverter@mullie.eu>
11
+ * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
12
+ * @license MIT License
13
+ */
14
+ interface ConverterInterface
15
+ {
16
+ /**
17
+ * Convert file paths.
18
+ *
19
+ * @param string $path The path to be converted
20
+ *
21
+ * @return string The new path
22
+ */
23
+ public function convert($path);
24
+ }
vendor/minifier/path-converter/src/NoConverter.php CHANGED
@@ -1,23 +1,23 @@
1
- <?php
2
-
3
- namespace MatthiasMullie\PathConverter;
4
-
5
- /**
6
- * Don't convert paths.
7
- *
8
- * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
9
- *
10
- * @author Matthias Mullie <pathconverter@mullie.eu>
11
- * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
12
- * @license MIT License
13
- */
14
- class NoConverter implements ConverterInterface
15
- {
16
- /**
17
- * {@inheritdoc}
18
- */
19
- public function convert($path)
20
- {
21
- return $path;
22
- }
23
- }
1
+ <?php
2
+
3
+ namespace MatthiasMullie\PathConverter;
4
+
5
+ /**
6
+ * Don't convert paths.
7
+ *
8
+ * Please report bugs on https://github.com/matthiasmullie/path-converter/issues
9
+ *
10
+ * @author Matthias Mullie <pathconverter@mullie.eu>
11
+ * @copyright Copyright (c) 2015, Matthias Mullie. All rights reserved
12
+ * @license MIT License
13
+ */
14
+ class NoConverter implements ConverterInterface
15
+ {
16
+ /**
17
+ * {@inheritdoc}
18
+ */
19
+ public function convert($path)
20
+ {
21
+ return $path;
22
+ }
23
+ }
wfu_file_downloader.php CHANGED
@@ -1,209 +1,211 @@
1
- <?php
2
- include_once( dirname(__FILE__).'/lib/wfu_functions.php' );
3
- include_once( dirname(__FILE__).'/lib/wfu_security.php' );
4
- $handler = (isset($_POST['handler']) ? $_POST['handler'] : (isset($_GET['handler']) ? $_GET['handler'] : '-1'));
5
- $session_legacy = (isset($_POST['session_legacy']) ? $_POST['session_legacy'] : (isset($_GET['session_legacy']) ? $_GET['session_legacy'] : ''));
6
- $dboption_base = (isset($_POST['dboption_base']) ? $_POST['dboption_base'] : (isset($_GET['dboption_base']) ? $_GET['dboption_base'] : '-1'));
7
- $dboption_useold = (isset($_POST['dboption_useold']) ? $_POST['dboption_useold'] : (isset($_GET['dboption_useold']) ? $_GET['dboption_useold'] : ''));
8
- $wfu_cookie = (isset($_POST['wfu_cookie']) ? $_POST['wfu_cookie'] : (isset($_GET['wfu_cookie']) ? $_GET['wfu_cookie'] : ''));
9
- if ( $handler == '-1' || $session_legacy == '' || $dboption_base == '-1' || $dboption_useold == '' || $wfu_cookie == '' ) die();
10
- else {
11
- $GLOBALS["wfu_user_state_handler"] = wfu_sanitize_code($handler);
12
- $GLOBALS["WFU_GLOBALS"]["WFU_US_SESSION_LEGACY"] = array( "", "", "", ( $session_legacy == '1' ? 'true' : 'false' ), "", true );
13
- $GLOBALS["WFU_GLOBALS"]["WFU_US_DBOPTION_BASE"] = array( "", "", "", wfu_sanitize_code($dboption_base), "", true );
14
- $GLOBALS["WFU_GLOBALS"]["WFU_US_DBOPTION_USEOLD"] = array( "", "", "", ( $dboption_useold == '1' ? 'true' : 'false' ), "", true );
15
- if ( !defined("WPFILEUPLOAD_COOKIE") ) DEFINE("WPFILEUPLOAD_COOKIE", wfu_sanitize_tag($wfu_cookie));
16
- wfu_download_file();
17
- }
18
-
19
- function wfu_download_file() {
20
- global $wfu_user_state_handler;
21
- $file_code = (isset($_POST['file']) ? $_POST['file'] : (isset($_GET['file']) ? $_GET['file'] : ''));
22
- $ticket = (isset($_POST['ticket']) ? $_POST['ticket'] : (isset($_GET['ticket']) ? $_GET['ticket'] : ''));
23
- if ( $file_code == '' || $ticket == '' ) die();
24
-
25
- wfu_initialize_user_state();
26
-
27
- $ticket = wfu_sanitize_code($ticket);
28
- $file_code = wfu_sanitize_code($file_code);
29
- //if download ticket does not exist or is expired die
30
- if ( !WFU_USVAR_exists_downloader('wfu_download_ticket_'.$ticket) || time() > WFU_USVAR_downloader('wfu_download_ticket_'.$ticket) ) {
31
- WFU_USVAR_unset_downloader('wfu_download_ticket_'.$ticket);
32
- WFU_USVAR_unset_downloader('wfu_storage_'.$file_code);
33
- wfu_update_download_status($ticket, 'failed');
34
- die();
35
- }
36
- //destroy ticket so it cannot be used again
37
- WFU_USVAR_unset_downloader('wfu_download_ticket_'.$ticket);
38
-
39
- //if file_code starts with exportdata, then this is a request for export of
40
- //uploaded file data, so disposition_name will not be the filename of the file
41
- //but wfu_export.csv; also set flag to delete file after download operation
42
- if ( substr($file_code, 0, 10) == "exportdata" ) {
43
- $file_code = substr($file_code, 10);
44
- //$filepath = wfu_get_filepath_from_safe($file_code);
45
- $filepath = WFU_USVAR_downloader('wfu_storage_'.$file_code);
46
- $disposition_name = "wfu_export.csv";
47
- $delete_file = true;
48
- }
49
- else {
50
- //$filepath = wfu_get_filepath_from_safe($file_code);
51
- $filepath = WFU_USVAR_downloader('wfu_storage_'.$file_code);
52
- if ( $filepath === false ) {
53
- WFU_USVAR_unset_downloader('wfu_storage_'.$file_code);
54
- wfu_update_download_status($ticket, 'failed');
55
- die();
56
- }
57
- $filepath = wfu_flatten_path($filepath);
58
- if ( substr($filepath, 0, 1) == "/" ) $filepath = substr($filepath, 1);
59
- $filepath = ( substr($filepath, 0, 6) == 'ftp://' || substr($filepath, 0, 7) == 'ftps://' || substr($filepath, 0, 7) == 'sftp://' ? $filepath : WFU_USVAR_downloader('wfu_ABSPATH').$filepath );
60
- $disposition_name = wfu_basename($filepath);
61
- $delete_file = false;
62
- }
63
- //destroy file code as it is no longer needed
64
- WFU_USVAR_unset_downloader('wfu_storage_'.$file_code);
65
- //check that file exists
66
- if ( !wfu_file_exists_for_downloader($filepath) ) {
67
- wfu_update_download_status($ticket, 'failed');
68
- die('<script language="javascript">alert("'.( WFU_USVAR_exists_downloader('wfu_browser_downloadfile_notexist') ? WFU_USVAR_downloader('wfu_browser_downloadfile_notexist') : 'File does not exist!' ).'");</script>');
69
- }
70
-
71
- $open_session = false;
72
- @set_time_limit(0); // disable the time limit for this script
73
- $fsize = wfu_filesize_for_downloader($filepath);
74
- if ( $fd = wfu_fopen_for_downloader($filepath, "rb") ) {
75
- $open_session = ( ( $wfu_user_state_handler == "session" || $wfu_user_state_handler == "" ) && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( empty(session_id()) ) ) );
76
- if ( $open_session ) session_start();
77
- header('Content-Type: application/octet-stream');
78
- header("Content-Disposition: attachment; filename=\"".$disposition_name."\"");
79
- header('Content-Transfer-Encoding: binary');
80
- header('Connection: Keep-Alive');
81
- header('Expires: 0');
82
- header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
83
- header('Pragma: public');
84
- header("Content-length: $fsize");
85
- $failed = false;
86
- while( !feof($fd) ) {
87
- $buffer = @fread($fd, 1024*8);
88
- echo $buffer;
89
- ob_flush();
90
- flush();
91
- if ( connection_status() != 0 ) {
92
- $failed = true;
93
- break;
94
- }
95
- }
96
- fclose ($fd);
97
- }
98
- else $failed = true;
99
-
100
- if ( $delete_file ) wfu_unlink_for_downloader($filepath);
101
-
102
- if ( !$failed ) {
103
- wfu_update_download_status($ticket, 'downloaded');
104
- if ( $open_session ) session_write_close();
105
- die();
106
- }
107
- else {
108
- wfu_update_download_status($ticket, 'failed');
109
- if ( $open_session ) session_write_close();
110
- die('<script type="text/javascript">alert("'.( WFU_USVAR_exists_downloader('wfu_browser_downloadfile_failed') ? WFU_USVAR_downloader('wfu_browser_downloadfile_failed') : 'Could not download file!' ).'");</script>');
111
- }
112
- }
113
-
114
- function wfu_update_download_status($ticket, $new_status) {
115
- require_once WFU_USVAR_downloader('wfu_ABSPATH').'wp-load.php';
116
- WFU_USVAR_store('wfu_download_status_'.$ticket, $new_status);
117
- }
118
-
119
- function WFU_USVAR_exists_downloader($var) {
120
- global $wfu_user_state_handler;
121
- if ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "cookies" ) return isset($_COOKIE[$var]);
122
- else return WFU_USVAR_exists_session($var);
123
- }
124
-
125
- function WFU_USVAR_downloader($var) {
126
- global $wfu_user_state_handler;
127
- if ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "cookies" ) return $_COOKIE[$var];
128
- else return WFU_USVAR_session($var);
129
- }
130
-
131
- function WFU_USVAR_unset_downloader($var) {
132
- global $wfu_user_state_handler;
133
- if ( $wfu_user_state_handler == "session" || $wfu_user_state_handler == "" ) WFU_USVAR_unset_session($var);
134
- }
135
-
136
- function wfu_file_exists_for_downloader($filepath) {
137
- if ( substr($filepath, 0, 7) != "sftp://" ) return file_exists($filepath);
138
- $ret = false;
139
- $ftpinfo = wfu_decode_ftpurl($filepath);
140
- if ( $ftpinfo["error"] ) return $ret;
141
- $data = $ftpinfo["data"];
142
- {
143
- $conn = @ssh2_connect($data["ftpdomain"], $data["port"]);
144
- if ( $conn && @ssh2_auth_password($conn, $data["username"], $data["password"]) ) {
145
- $sftp = @ssh2_sftp($conn);
146
- $ret = ( $sftp && @file_exists("ssh2.sftp://".intval($sftp).$data["filepath"]) );
147
- }
148
- }
149
-
150
- return $ret;
151
- }
152
-
153
- function wfu_filesize_for_downloader($filepath) {
154
- if ( substr($filepath, 0, 7) != "sftp://" ) return filesize($filepath);
155
- $ret = false;
156
- $ftpinfo = wfu_decode_ftpurl($filepath);
157
- if ( $ftpinfo["error"] ) return $ret;
158
- $data = $ftpinfo["data"];
159
- {
160
- $conn = @ssh2_connect($data["ftpdomain"], $data["port"]);
161
- if ( $conn && @ssh2_auth_password($conn, $data["username"], $data["password"]) ) {
162
- $sftp = @ssh2_sftp($conn);
163
- if ( $sftp ) $ret = @filesize("ssh2.sftp://".intval($sftp).$data["filepath"]);
164
- }
165
- }
166
-
167
- return $ret;
168
- }
169
-
170
- function wfu_fopen_for_downloader($filepath, $mode) {
171
- if ( substr($filepath, 0, 7) != "sftp://" ) return @fopen($filepath, $mode);
172
- $ret = false;
173
- $ftpinfo = wfu_decode_ftpurl($filepath);
174
- if ( $ftpinfo["error"] ) return $ret;
175
- $data = $ftpinfo["data"];
176
- {
177
- $conn = @ssh2_connect($data["ftpdomain"], $data["port"]);
178
- if ( $conn && @ssh2_auth_password($conn, $data["username"], $data["password"]) ) {
179
- $sftp = @ssh2_sftp($conn);
180
- if ( $sftp ) {
181
- //$ret = @fopen("ssh2.sftp://".intval($sftp).$data["filepath"], $mode);
182
- $contents = @file_get_contents("ssh2.sftp://".intval($sftp).$data["filepath"]);
183
- $stream = fopen('php://memory', 'r+');
184
- fwrite($stream, $contents);
185
- rewind($stream);
186
- $ret = $stream;
187
- }
188
- }
189
- }
190
-
191
- return $ret;
192
- }
193
-
194
- function wfu_unlink_for_downloader($filepath) {
195
- if ( substr($filepath, 0, 7) != "sftp://" ) return @unlink($filepath);
196
- $ret = false;
197
- $ftpinfo = wfu_decode_ftpurl($filepath);
198
- if ( $ftpinfo["error"] ) return $ret;
199
- $data = $ftpinfo["data"];
200
- {
201
- $conn = @ssh2_connect($data["ftpdomain"], $data["port"]);
202
- if ( $conn && @ssh2_auth_password($conn, $data["username"], $data["password"]) ) {
203
- $sftp = @ssh2_sftp($conn);
204
- if ( $sftp ) $ret = @unlink("ssh2.sftp://".intval($sftp).$data["filepath"]);
205
- }
206
- }
207
-
208
- return $ret;
 
 
209
  }
1
+ <?php
2
+ if ( !defined("ABSWPFILEUPLOAD_DIR") ) DEFINE("ABSWPFILEUPLOAD_DIR", dirname(__FILE__).'/');
3
+ if ( !defined("WFU_AUTOLOADER_PHP50600") ) DEFINE("WFU_AUTOLOADER_PHP50600", 'vendor/modules/php5.6/autoload.php');
4
+ include_once( ABSWPFILEUPLOAD_DIR.'lib/wfu_functions.php' );
5
+ include_once( ABSWPFILEUPLOAD_DIR.'lib/wfu_security.php' );
6
+ $handler = (isset($_POST['handler']) ? $_POST['handler'] : (isset($_GET['handler']) ? $_GET['handler'] : '-1'));
7
+ $session_legacy = (isset($_POST['session_legacy']) ? $_POST['session_legacy'] : (isset($_GET['session_legacy']) ? $_GET['session_legacy'] : ''));
8
+ $dboption_base = (isset($_POST['dboption_base']) ? $_POST['dboption_base'] : (isset($_GET['dboption_base']) ? $_GET['dboption_base'] : '-1'));
9
+ $dboption_useold = (isset($_POST['dboption_useold']) ? $_POST['dboption_useold'] : (isset($_GET['dboption_useold']) ? $_GET['dboption_useold'] : ''));
10
+ $wfu_cookie = (isset($_POST['wfu_cookie']) ? $_POST['wfu_cookie'] : (isset($_GET['wfu_cookie']) ? $_GET['wfu_cookie'] : ''));
11
+ if ( $handler == '-1' || $session_legacy == '' || $dboption_base == '-1' || $dboption_useold == '' || $wfu_cookie == '' ) die();
12
+ else {
13
+ $GLOBALS["wfu_user_state_handler"] = wfu_sanitize_code($handler);
14
+ $GLOBALS["WFU_GLOBALS"]["WFU_US_SESSION_LEGACY"] = array( "", "", "", ( $session_legacy == '1' ? 'true' : 'false' ), "", true );
15
+ $GLOBALS["WFU_GLOBALS"]["WFU_US_DBOPTION_BASE"] = array( "", "", "", wfu_sanitize_code($dboption_base), "", true );
16
+ $GLOBALS["WFU_GLOBALS"]["WFU_US_DBOPTION_USEOLD"] = array( "", "", "", ( $dboption_useold == '1' ? 'true' : 'false' ), "", true );
17
+ if ( !defined("WPFILEUPLOAD_COOKIE") ) DEFINE("WPFILEUPLOAD_COOKIE", wfu_sanitize_tag($wfu_cookie));
18
+ wfu_download_file();
19
+ }
20
+
21
+ function wfu_download_file() {
22
+ global $wfu_user_state_handler;
23
+ $file_code = (isset($_POST['file']) ? $_POST['file'] : (isset($_GET['file']) ? $_GET['file'] : ''));
24
+ $ticket = (isset($_POST['ticket']) ? $_POST['ticket'] : (isset($_GET['ticket']) ? $_GET['ticket'] : ''));
25
+ if ( $file_code == '' || $ticket == '' ) die();
26
+
27
+ wfu_initialize_user_state();
28
+
29
+ $ticket = wfu_sanitize_code($ticket);
30
+ $file_code = wfu_sanitize_code($file_code);
31
+ //if download ticket does not exist or is expired die
32
+ if ( !WFU_USVAR_exists_downloader('wfu_download_ticket_'.$ticket) || time() > WFU_USVAR_downloader('wfu_download_ticket_'.$ticket) ) {
33
+ WFU_USVAR_unset_downloader('wfu_download_ticket_'.$ticket);
34
+ WFU_USVAR_unset_downloader('wfu_storage_'.$file_code);
35
+ wfu_update_download_status($ticket, 'failed');
36
+ die();
37
+ }
38
+ //destroy ticket so it cannot be used again
39
+ WFU_USVAR_unset_downloader('wfu_download_ticket_'.$ticket);
40
+
41
+ //if file_code starts with exportdata, then this is a request for export of
42
+ //uploaded file data, so disposition_name will not be the filename of the file
43
+ //but wfu_export.csv; also set flag to delete file after download operation
44
+ if ( substr($file_code, 0, 10) == "exportdata" ) {
45
+ $file_code = substr($file_code, 10);
46
+ //$filepath = wfu_get_filepath_from_safe($file_code);
47
+ $filepath = WFU_USVAR_downloader('wfu_storage_'.$file_code);
48
+ $disposition_name = "wfu_export.csv";
49
+ $delete_file = true;
50
+ }
51
+ else {
52
+ //$filepath = wfu_get_filepath_from_safe($file_code);
53
+ $filepath = WFU_USVAR_downloader('wfu_storage_'.$file_code);
54
+ if ( $filepath === false ) {
55
+ WFU_USVAR_unset_downloader('wfu_storage_'.$file_code);
56
+ wfu_update_download_status($ticket, 'failed');
57
+ die();
58
+ }
59
+ $filepath = wfu_flatten_path($filepath);
60
+ if ( substr($filepath, 0, 1) == "/" ) $filepath = substr($filepath, 1);
61
+ $filepath = ( substr($filepath, 0, 6) == 'ftp://' || substr($filepath, 0, 7) == 'ftps://' || substr($filepath, 0, 7) == 'sftp://' ? $filepath : WFU_USVAR_downloader('wfu_ABSPATH').$filepath );
62
+ $disposition_name = wfu_basename($filepath);
63
+ $delete_file = false;
64
+ }
65
+ //destroy file code as it is no longer needed
66
+ WFU_USVAR_unset_downloader('wfu_storage_'.$file_code);
67
+ //check that file exists
68
+ if ( !wfu_file_exists_for_downloader($filepath) ) {
69
+ wfu_update_download_status($ticket, 'failed');
70
+ die('<script language="javascript">alert("'.( WFU_USVAR_exists_downloader('wfu_browser_downloadfile_notexist') ? WFU_USVAR_downloader('wfu_browser_downloadfile_notexist') : 'File does not exist!' ).'");</script>');
71
+ }
72
+
73
+ $open_session = false;
74
+ @set_time_limit(0); // disable the time limit for this script
75
+ $fsize = wfu_filesize_for_downloader($filepath);
76
+ if ( $fd = wfu_fopen_for_downloader($filepath, "rb") ) {
77
+ $open_session = ( ( $wfu_user_state_handler == "session" || $wfu_user_state_handler == "" ) && ( function_exists("session_status") ? ( PHP_SESSION_ACTIVE !== session_status() ) : ( empty(session_id()) ) ) );
78
+ if ( $open_session ) session_start();
79
+ header('Content-Type: application/octet-stream');
80
+ header("Content-Disposition: attachment; filename=\"".$disposition_name."\"");
81
+ header('Content-Transfer-Encoding: binary');
82
+ header('Connection: Keep-Alive');
83
+ header('Expires: 0');
84
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
85
+ header('Pragma: public');
86
+ header("Content-length: $fsize");
87
+ $failed = false;
88
+ while( !feof($fd) ) {
89
+ $buffer = @fread($fd, 1024*8);
90
+ echo $buffer;
91
+ ob_flush();
92
+ flush();
93
+ if ( connection_status() != 0 ) {
94
+ $failed = true;
95
+ break;
96
+ }
97
+ }
98
+ fclose ($fd);
99
+ }
100
+ else $failed = true;
101
+
102
+ if ( $delete_file ) wfu_unlink_for_downloader($filepath);
103
+
104
+ if ( !$failed ) {
105
+ wfu_update_download_status($ticket, 'downloaded');
106
+ if ( $open_session ) session_write_close();
107
+ die();
108
+ }
109
+ else {
110
+ wfu_update_download_status($ticket, 'failed');
111
+ if ( $open_session ) session_write_close();
112
+ die('<script type="text/javascript">alert("'.( WFU_USVAR_exists_downloader('wfu_browser_downloadfile_failed') ? WFU_USVAR_downloader('wfu_browser_downloadfile_failed') : 'Could not download file!' ).'");</script>');
113
+ }
114
+ }
115
+
116
+ function wfu_update_download_status($ticket, $new_status) {
117
+ require_once WFU_USVAR_downloader('wfu_ABSPATH').'wp-load.php';
118
+ WFU_USVAR_store('wfu_download_status_'.$ticket, $new_status);
119
+ }
120
+
121
+ function WFU_USVAR_exists_downloader($var) {
122
+ global $wfu_user_state_handler;
123
+ if ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "cookies" ) return isset($_COOKIE[$var]);
124
+ else return WFU_USVAR_exists_session($var);
125
+ }
126
+
127
+ function WFU_USVAR_downloader($var) {
128
+ global $wfu_user_state_handler;
129
+ if ( $wfu_user_state_handler == "dboption" && WFU_VAR("WFU_US_DBOPTION_BASE") == "cookies" ) return $_COOKIE[$var];
130
+ else return WFU_USVAR_session($var);
131
+ }
132
+
133
+ function WFU_USVAR_unset_downloader($var) {
134
+ global $wfu_user_state_handler;
135
+ if ( $wfu_user_state_handler == "session" || $wfu_user_state_handler == "" ) WFU_USVAR_unset_session($var);
136
+ }
137
+
138
+ function wfu_file_exists_for_downloader($filepath) {
139
+ if ( substr($filepath, 0, 7) != "sftp://" ) return file_exists($filepath);
140
+ $ret = false;
141
+ $ftpinfo = wfu_decode_ftpurl($filepath);
142
+ if ( $ftpinfo["error"] ) return $ret;
143
+ $data = $ftpinfo["data"];
144
+ {
145
+ $conn = @ssh2_connect($data["ftpdomain"], $data["port"]);
146
+ if ( $conn && @ssh2_auth_password($conn, $data["username"], $data["password"]) ) {
147
+ $sftp = @ssh2_sftp($conn);
148
+ $ret = ( $sftp && @file_exists("ssh2.sftp://".intval($sftp).$data["filepath"]) );
149
+ }
150
+ }
151
+
152
+ return $ret;
153
+ }
154
+
155
+ function wfu_filesize_for_downloader($filepath) {
156
+ if ( substr($filepath, 0, 7) != "sftp://" ) return filesize($filepath);
157
+ $ret = false;
158
+ $ftpinfo = wfu_decode_ftpurl($filepath);
159
+ if ( $ftpinfo["error"] ) return $ret;
160
+ $data = $ftpinfo["data"];
161
+ {
162
+ $conn = @ssh2_connect($data["ftpdomain"], $data["port"]);
163
+ if ( $conn && @ssh2_auth_password($conn, $data["username"], $data["password"]) ) {
164
+ $sftp = @ssh2_sftp($conn);
165
+ if ( $sftp ) $ret = @filesize("ssh2.sftp://".intval($sftp).$data["filepath"]);
166
+ }
167
+ }
168
+
169
+ return $ret;
170
+ }
171
+
172
+ function wfu_fopen_for_downloader($filepath, $mode) {
173
+ if ( substr($filepath, 0, 7) != "sftp://" ) return @fopen($filepath, $mode);
174
+ $ret = false;
175
+ $ftpinfo = wfu_decode_ftpurl($filepath);
176
+ if ( $ftpinfo["error"] ) return $ret;
177
+ $data = $ftpinfo["data"];
178
+ {
179
+ $conn = @ssh2_connect($data["ftpdomain"], $data["port"]);
180
+ if ( $conn && @ssh2_auth_password($conn, $data["username"], $data["password"]) ) {
181
+ $sftp = @ssh2_sftp($conn);
182
+ if ( $sftp ) {
183
+ //$ret = @fopen("ssh2.sftp://".intval($sftp).$data["filepath"], $mode);
184
+ $contents = @file_get_contents("ssh2.sftp://".intval($sftp).$data["filepath"]);
185
+ $stream = fopen('php://memory', 'r+');
186
+ fwrite($stream, $contents);
187
+ rewind($stream);
188
+ $ret = $stream;
189
+ }
190
+ }
191
+ }
192
+
193
+ return $ret;
194
+ }
195
+
196
+ function wfu_unlink_for_downloader($filepath) {
197
+ if ( substr($filepath, 0, 7) != "sftp://" ) return @unlink($filepath);
198
+ $ret = false;
199
+ $ftpinfo = wfu_decode_ftpurl($filepath);
200
+ if ( $ftpinfo["error"] ) return $ret;
201
+ $data = $ftpinfo["data"];
202
+ {
203
+ $conn = @ssh2_connect($data["ftpdomain"], $data["port"]);
204
+ if ( $conn && @ssh2_auth_password($conn, $data["username"], $data["password"]) ) {
205
+ $sftp = @ssh2_sftp($conn);
206
+ if ( $sftp ) $ret = @unlink("ssh2.sftp://".intval($sftp).$data["filepath"]);
207
+ }
208
+ }
209
+
210
+ return $ret;
211
  }
wfu_loader.php CHANGED
@@ -1,1014 +1,1015 @@
1
- <?php
2
-
3
- /**
4
- * Initialize plugin
5
- *
6
- * This file initializes the plugin; defines constants, loads plugin's files,
7
- * defines shortcodes and text domain, registers filters and actions and
8
- * processes website requests.
9
- *
10
- * @link /wfu_loader.php
11
- *
12
- * @package WordPress File Upload Plugin
13
- * @subpackage Core Components
14
- * @since 4.9.1
15
- */
16
-
17
- if ( !defined("WPFILEUPLOAD_PLUGINFILE") ) return;
18
-
19
- //set global db variables
20
- //wfu_tb_log_version v2.0 changes:
21
- // sessionid field added
22
- //wfu_tb_log_version v3.0 changes:
23
- // uploadtime field added
24
- // blogid field added
25
- //wfu_tb_log_version v4.0 changes:
26
- // filedata field added
27
- $wfu_tb_log_version = "4.0";
28
- $wfu_tb_userdata_version = "1.0";
29
- $wfu_tb_dbxqueue_version = "1.0";
30
-
31
- DEFINE("WPFILEUPLOAD_DIR", plugin_dir_url( WPFILEUPLOAD_PLUGINFILE ));
32
- DEFINE("ABSWPFILEUPLOAD_DIR", plugin_dir_path( WPFILEUPLOAD_PLUGINFILE ));
33
- if ( !defined("WPFILEUPLOAD_COOKIE") ) {
34
- if ( defined("COOKIEHASH") ) DEFINE("WPFILEUPLOAD_COOKIE", "wp_wpfileupload_".COOKIEHASH);
35
- else DEFINE("WPFILEUPLOAD_COOKIE", "wp_wpfileupload_0");
36
- }
37
- add_shortcode("wordpress_file_upload", "wordpress_file_upload_handler");
38
- //activation-deactivation hooks
39
- register_activation_hook(WPFILEUPLOAD_PLUGINFILE,'wordpress_file_upload_install');
40
- register_deactivation_hook(WPFILEUPLOAD_PLUGINFILE,'wordpress_file_upload_uninstall');
41
- add_action('plugins_loaded', 'wordpress_file_upload_initialize');
42
- add_action('plugins_loaded', 'wordpress_file_upload_update_db_check');
43
- //widget
44
- add_action( 'widgets_init', 'register_wfu_widget' );
45
- //admin hooks
46
- add_action('admin_init', 'wordpress_file_upload_admin_init');
47
- add_action('admin_menu', 'wordpress_file_upload_add_admin_pages');
48
- //load styles and scripts for front pages
49
- if ( !is_admin() ) {
50
- add_action( 'wp_enqueue_scripts', 'wfu_enqueue_frontpage_scripts' );
51
- }
52
- //add admin bar menu item of new uploaded files
53
- add_action( 'wp_before_admin_bar_render', 'wfu_admin_toolbar_new_uploads', 999 );
54
- //general ajax actions
55
- add_action('wp_ajax_wfu_ajax_action', 'wfu_ajax_action_callback');
56
- add_action('wp_ajax_nopriv_wfu_ajax_action', 'wfu_ajax_action_callback');
57
- add_action('wp_ajax_wfu_ajax_action_ask_server', 'wfu_ajax_action_ask_server');
58
- add_action('wp_ajax_nopriv_wfu_ajax_action_ask_server', 'wfu_ajax_action_ask_server');
59
- add_action('wp_ajax_wfu_ajax_action_cancel_upload', 'wfu_ajax_action_cancel_upload');
60
- add_action('wp_ajax_nopriv_wfu_ajax_action_cancel_upload', 'wfu_ajax_action_cancel_upload');
61
- add_action('wp_ajax_wfu_ajax_action_send_email_notification', 'wfu_ajax_action_send_email_notification');
62
- add_action('wp_ajax_nopriv_wfu_ajax_action_send_email_notification', 'wfu_ajax_action_send_email_notification');
63
- add_action('wp_ajax_wfu_ajax_action_notify_wpfilebase', 'wfu_ajax_action_notify_wpfilebase');
64
- add_action('wp_ajax_nopriv_wfu_ajax_action_notify_wpfilebase', 'wfu_ajax_action_notify_wpfilebase');
65
- add_action('wp_ajax_wfu_ajax_action_save_shortcode', 'wfu_ajax_action_save_shortcode');
66
- add_action('wp_ajax_wfu_ajax_action_check_page_contents', 'wfu_ajax_action_check_page_contents');
67
- add_action('wp_ajax_wfu_ajax_action_read_subfolders', 'wfu_ajax_action_read_subfolders');
68
- add_action('wp_ajax_wfu_ajax_action_download_file_invoker', 'wfu_ajax_action_download_file_invoker');
69
- add_action('wp_ajax_nopriv_wfu_ajax_action_download_file_invoker', 'wfu_ajax_action_download_file_invoker');
70
- add_action('wp_ajax_wfu_ajax_action_download_file_monitor', 'wfu_ajax_action_download_file_monitor');
71
- add_action('wp_ajax_nopriv_wfu_ajax_action_download_file_monitor', 'wfu_ajax_action_download_file_monitor');
72
- add_action('wp_ajax_wfu_ajax_action_edit_shortcode', 'wfu_ajax_action_edit_shortcode');
73
- add_action('wp_ajax_wfu_ajax_action_gutedit_shortcode', 'wfu_ajax_action_gutedit_shortcode');
74
- add_action('wp_ajax_wfu_ajax_action_get_historylog_page', 'wfu_ajax_action_get_historylog_page');
75
- add_action('wp_ajax_wfu_ajax_action_get_uploadedfiles_page', 'wfu_ajax_action_get_uploadedfiles_page');
76
- add_action('wp_ajax_wfu_ajax_action_get_adminbrowser_page', 'wfu_ajax_action_get_adminbrowser_page');
77
- add_action('wp_ajax_wfu_ajax_action_include_file', 'wfu_ajax_action_include_file');
78
- add_action('wp_ajax_wfu_ajax_action_update_envar', 'wfu_ajax_action_update_envar');
79
- add_action('wp_ajax_wfu_ajax_action_transfer_command', 'wfu_ajax_action_transfer_command');
80
- add_action('wp_ajax_wfu_ajax_action_pdusers_get_users', 'wfu_ajax_action_pdusers_get_users');
81
- //personal data related actions
82
- add_action( 'show_user_profile', 'wfu_show_consent_profile_fields' );
83
- add_action( 'edit_user_profile', 'wfu_show_consent_profile_fields' );
84
- add_action( 'personal_options_update', 'wfu_update_consent_profile_fields' );
85
- add_action( 'edit_user_profile_update', 'wfu_update_consent_profile_fields' );
86
- //Media editor custom properties
87
- if ( is_admin() ) add_action( 'attachment_submitbox_misc_actions', 'wfu_media_editor_properties', 11 );
88
- //register admin filter to check consent status before upload
89
- add_filter("wfu_before_upload", "wfu_consent_ask_server_handler", 10, 2);
90
- //register internal filter that is executed before upload for classic uploader
91
- add_filter("_wfu_before_upload", "wfu_classic_before_upload_handler", 10, 2);
92
- wfu_include_lib();
93
-
94
- /**
95
- * Initialize plugin.
96
- *
97
- * Runs after plugins are loaded in order to correctly load the plugin's text
98
- * domain and then load all translatable strings. Then it loads the User State
99
- * Handler (session or db). Then it executes all active plugin hooks.
100
- *
101
- * @since 4.7.0
102
- *
103
- * @redeclarable
104
- */
105
- function wordpress_file_upload_initialize() {
106
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
107
- $loaded = load_plugin_textdomain('wp-file-upload', false, dirname(plugin_basename (WPFILEUPLOAD_PLUGINFILE)).'/languages');
108
- wfu_initialize_i18n_strings();
109
- //store the User State handler in a global variable for easy access by the
110
- //plugin's routines
111
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
112
- $GLOBALS["wfu_user_state_handler"] = $plugin_options['userstatehandler'];
113
- wfu_initialize_user_state();
114
-
115
- }
116
-
117
- /**
118
- * Register Upload Form Widget.
119
- *
120
- * Runs on widget initialization to register the upload form widget of the
121
- * plugin.
122
- *
123
- * @since 3.4.0
124
- */
125
- function register_wfu_widget() {
126
- /**
127
- * Allow Custom Scripts to Register WFU Widget.
128
- *
129
- * This filter allows custom scripts to register the WFU widget in their own
130
- * was.
131
- *
132
- * @since 4.12.2
133
- *
134
- * @param bool $processed True if the filter has completed registration or
135
- * false otherwise.
136
- */
137
- $processed = apply_filters("_register_wfu_widget", false);
138
- if ( !$processed ) register_widget( 'WFU_Widget' );
139
- }
140
-
141
- /**
142
- * Enqueue frontpage styles and scripts.
143
- *
144
- * It enqueues all necessary frontpage styles and scripts of the plugin.
145
- *
146
- * @since 2.4.6
147
- *
148
- * @redeclarable
149
- */
150
- function wfu_enqueue_frontpage_scripts() {
151
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
152
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
153
- $relaxcss = false;
154
- if ( isset($plugin_options['relaxcss']) ) $relaxcss = ( $plugin_options['relaxcss'] == '1' );
155
- //apply wfu_before_frontpage_scripts to get additional settings
156
- $changable_data = array();
157
- /**
158
- * Execute Custom Actions Before Loading Frontpage Scripts.
159
- *
160
- * This filter allows to execute custom actions before frontpage scripts are
161
- * loaded. Loading of plugin's scripts can be completely customised.
162
- *
163
- * @since 3.5.0
164
- *
165
- * @param array $changable_data {
166
- * Controls loading of frontpage scripts.
167
- *
168
- * @type mixed $return_value Optional. If it is set then no frontpage
169
- * scripts will be loaded.
170
- * @type string $correct_NextGenGallery_incompatibility Optional. If it
171
- * is set to "true" then JQuery UI styles will not be loaded in
172
- * order to avoid incompatibility with NextGEN Gallery plugin.
173
- * @type string $correct_JQueryUI_incompatibility Optional. If it is set
174
- * to "true" then JQuery UI styles will not be loaded (same as
175
- * previous parameter).
176
- * @type string $exclude_timepicker Optional. If it is set to "true"
177
- * then jQuery timepicker styles and scripts will not be loaded.
178
- * }
179
- */
180
- $ret_data = apply_filters('wfu_before_frontpage_scripts', $changable_data);
181
- //if $ret_data contains 'return_value' key then no scripts will be enqueued
182
- if ( isset($ret_data['return_value']) ) return $ret_data['return_value'];
183
-
184
- if ( $relaxcss ) {
185
- wp_enqueue_style('wordpress-file-upload-style', WPFILEUPLOAD_DIR.'css/wordpress_file_upload_style_relaxed.css');
186
- wp_enqueue_style('wordpress-file-upload-style-safe', WPFILEUPLOAD_DIR.'css/wordpress_file_upload_style_safe_relaxed.css');
187
- }
188
- else {
189
- wp_enqueue_style('wordpress-file-upload-style', WPFILEUPLOAD_DIR.'css/wordpress_file_upload_style.css');
190
- wp_enqueue_style('wordpress-file-upload-style-safe', WPFILEUPLOAD_DIR.'css/wordpress_file_upload_style_safe.css');
191
- }
192
- wp_enqueue_style('wordpress-file-upload-adminbar-style', WPFILEUPLOAD_DIR.'css/wordpress_file_upload_adminbarstyle.css');
193
- //do not load JQuery UI css if $ret_data denotes incompatibility issues
194
- if ( ( !isset($ret_data["correct_NextGenGallery_incompatibility"]) || $ret_data["correct_NextGenGallery_incompatibility"] != "true" ) &&
195
- ( !isset($ret_data["correct_JQueryUI_incompatibility"]) || $ret_data["correct_JQueryUI_incompatibility"] != "true" ) )
196
- wp_enqueue_style('jquery-ui-css', WPFILEUPLOAD_DIR.'vendor/jquery/jquery-ui.min.css');
197
- //do not load timepicker css if $ret_data exclude_timepicker flag is true
198
- if ( !isset($ret_data["exclude_timepicker"]) || $ret_data["exclude_timepicker"] != "true" )
199
- wp_enqueue_style('jquery-ui-timepicker-addon-css', WPFILEUPLOAD_DIR.'vendor/jquery/jquery-ui-timepicker-addon.min.css');
200
- wp_enqueue_script('json2');
201
- wp_enqueue_script('wordpress_file_upload_script', WPFILEUPLOAD_DIR.'js/wordpress_file_upload_functions.js');
202
- //do not load timepicker js if $ret_data exclude_timepicker flag is true
203
- if ( !isset($ret_data["exclude_timepicker"]) || $ret_data["exclude_timepicker"] != "true" ) {
204
- wp_enqueue_script('jquery-ui-slider');
205
- wp_enqueue_script('jquery-ui-timepicker-addon-js', WPFILEUPLOAD_DIR.'vendor/jquery/jquery-ui-timepicker-addon.min.js', array("jquery-ui-datepicker"));
206
- }
207
- }
208
-
209
- /**
210
- * Load plugin libraries.
211
- *
212
- * It loads all plugin libraries located in /lib folder of the plugin.
213
- *
214
- * @since 2.1.2
215
- */
216
- function wfu_include_lib() {
217
- $dir = plugin_dir_path( WPFILEUPLOAD_PLUGINFILE )."lib/";
218
- if ( $handle = opendir($dir) ) {
219
- $blacklist = array('.', '..');
220
- while ( false !== ($file = readdir($handle)) )
221
- if ( !in_array($file, $blacklist) && substr($file, 0, 1) != "_" )
222
- include_once $dir.$file;
223
- closedir($handle);
224
- }
225
- if ( $handle = opendir(plugin_dir_path( WPFILEUPLOAD_PLUGINFILE )) ) {
226
- closedir($handle);
227
- }
228
- }
229
-
230
-
231
- /* exit if we are in admin pages (in case of ajax call) */
232
- if ( is_admin() ) return;
233
-
234
- /**
235
- * Render uploader form shortcode.
236
- *
237
- * It receives the attributes of an uploader form shortcode and returns the HTML
238
- * code of the generated upload form.
239
- *
240
- * @since 2.1.2
241
- *
242
- * @param array $incomingfrompost An associative array of shortcode attributes
243
- * (array keys) and their values (array values).
244
- * @return string The HTML code of the generated upload form
245
- */
246
- function wordpress_file_upload_handler($incomingfrompost) {
247
- //replace old attribute definitions with new ones
248
- $incomingfrompost = wfu_old_to_new_attributes($incomingfrompost);
249
- //preprocess attributes
250
- $incomingfrompost = wfu_preprocess_attributes($incomingfrompost);
251
- //process incoming attributes assigning defaults if required
252
- $defs_indexed = wfu_shortcode_attribute_definitions_adjusted($incomingfrompost);
253
- $incomingfrompost = shortcode_atts($defs_indexed, $incomingfrompost);
254
- //run function that actually does the work of the plugin
255
- $wordpress_file_upload_output = wordpress_file_upload_function($incomingfrompost);
256
- //send back text to replace shortcode in post
257
- return $wordpress_file_upload_output;
258
- }
259
-
260
- /**
261
- * Render front-end file viewer shortcode.
262
- *
263
- * It receives the attributes of a front-end file viewer shortcode and returns
264
- * the HTML code of the generated file viewer.
265
- *
266
- * @since 3.1.0
267
- *
268
- * @param array $incomingfrompost An associative array of shortcode attributes
269
- * (array keys) and their values (array values).
270
- * @return string The HTML code of the generated file viewer
271
- */
272
- function wordpress_file_upload_browser_handler($incomingfrompost) {
273
- //process incoming attributes assigning defaults if required
274
- $defs = wfu_browser_attribute_definitions();
275
- $defs_indexed = array();
276
- foreach ( $defs as $def ) $defs_indexed[$def["attribute"]] = $def["value"];
277
- $incomingfrompost = shortcode_atts($defs_indexed, $incomingfrompost);
278
- //run function that actually does the work of the plugin
279
- $wordpress_file_upload_browser_output = wordpress_file_upload_browser_function($incomingfrompost);
280
- //send back text to replace shortcode in post
281
- return $wordpress_file_upload_browser_output;
282
- }
283
-
284
- /**
285
- * Generate the HTML code of uploader form.
286
- *
287
- * It receives the processed attributes of an uploader form shortcode and
288
- * returns the HTML code of the generated upload form.
289
- *
290
- * @since 2.1.2
291
- *
292
- * @redeclarable
293
- *
294
- * @global object $post The current post
295
- * @global int $blog_id The ID of the current blog
296
- *
297
- * @param array $incomingfromhandler An associative array of shortcode
298
- * attributes (array keys) and their values (array values).
299
- *
300
- * @return string The HTML code of the generated upload form
301
- */
302
- function wordpress_file_upload_function($incomingfromhandler) {
303
- $a = func_get_args(); $a = WFU_FUNCTION_HOOK(__FUNCTION__, $a, $out); if (isset($out['vars'])) foreach($out['vars'] as $p => $v) $$p = $v; switch($a) { case 'R': return $out['output']; break; case 'D': die($out['output']); }
304
- global $post;
305
- global $blog_id;
306
-
307
- $plugin_options = wfu_decode_plugin_options(get_option( "wordpress_file_upload_options" ));
308
- $shortcode_tag = 'wordpress_file_upload';
309
- $params = wfu_plugin_parse_array($incomingfromhandler);
310
- //sanitize params
311
- $params = wfu_sanitize_shortcode_array($params, $shortcode_tag);
312
-
313
- $is_admin = current_user_can( 'manage_options' );
314
- //check if a non-admin user can edit the shortcode
315
- $can_open_composer = ( WFU_VAR("WFU_SHORTCODECOMPOSER_NOADMIN") == "true" &&
316
- $params["widgetid"] == "" &&
317
- $post != null &&
318
- isset($post->post_type) &&
319
- ( $post->post_type == 'post' || $post->post_type == 'page' ) &&
320
- current_user_can( 'edit_'.$post->post_type, $post->ID ) );
321
- //take into account if the user is admin
322
- $can_open_composer = ( $is_admin || $can_open_composer );
323
- /**
324
- * Filter To Customise Shortcode Composer Permission.
325
- *
326
- * This filter is used to customise the permissions of the user to open the
327
- * shortcode composer.
328
- *
329
- * @since 4.12.2
330
- *
331
- * @param bool $can_open_composer Whether the composer can be opened or not.
332
- * @param array $params An associative array with shortcode attributes.
333
- */
334
- $can_open_composer = apply_filters("_wfu_can_open_composer", $can_open_composer, $params);
335
-
336
- $sid = $params["uploadid"];
337
- // store current page and blog id in params array
338
- $params["pageid"] = $post->ID;
339
- $params["blogid"] = $blog_id;
340
-
341
- $token_sid = 'wfu_token_'.$sid;
342
- if ( !WFU_USVAR_exists($token_sid) || WFU_USVAR($token_sid) == "" )
343
- WFU_USVAR_store($token_sid, uniqid(mt_rand(), TRUE));
344
- //store the server environment (32 or 64bit) for use when checking file size limits
345
- $params["php_env"] = wfu_get_server_environment();
346
-
347
- $user = wp_get_current_user();
348
- $widths = wfu_decode_dimensions($params["widths"]);
349
- $heights = wfu_decode_dimensions($params["heights"]);
350
- //additional parameters to pass to visualization routines
351
- $additional_params = array( );
352
- $additional_params['widths'] = $widths;
353
- $additional_params['heights'] = $heights;
354
- $additional_params["require_consent"] = ( $plugin_options["personaldata"] == "