diff options
Diffstat (limited to 'wp-admin')
78 files changed, 15449 insertions, 273 deletions
diff --git a/wp-admin/async-upload.php b/wp-admin/async-upload.php new file mode 100644 index 0000000..c6350aa --- /dev/null +++ b/wp-admin/async-upload.php @@ -0,0 +1,32 @@ +<?php + +/* This accepts file uploads from swfupload or other asynchronous upload methods. + +*/ + +if ( defined('ABSPATH') ) + require_once( ABSPATH . 'wp-config.php'); +else + require_once('../wp-config.php'); + +// Flash often fails to send cookies with the POST or upload, so we need to pass it in GET or POST instead +if ( empty($_COOKIE[AUTH_COOKIE]) && !empty($_REQUEST['auth_cookie']) ) + $_COOKIE[AUTH_COOKIE] = $_REQUEST['auth_cookie']; +unset($current_user); +require_once('admin.php'); + +header('Content-Type: text/plain'); + +if ( !current_user_can('upload_files') ) + wp_die(__('You do not have permission to upload files.')); + +$id = media_handle_upload('async-upload', $_REQUEST['post_id']); +if (is_wp_error($id)) { + echo '<div id="media-upload-error">'.wp_specialchars($id->get_error_message()).'</div>'; + exit; +} + +$type = $_REQUEST['type']; +echo apply_filters("async_upload_{$type}", $id); + +?> diff --git a/wp-admin/css/colors-classic.css b/wp-admin/css/colors-classic.css new file mode 100644 index 0000000..4251f15 --- /dev/null +++ b/wp-admin/css/colors-classic.css @@ -0,0 +1,701 @@ +a.page-numbers:hover { + border-color: #999; +} + +body { + background-color: #fff; + color: #333; +} + +body > #upload-menu { + border-bottom-style: #fff; +} + +div#current-widgets, #postcustomstuff table, #your-profile fieldset, a.page-numbers, #rightnow, div.dashboard-widget, .widefat { + border-color: #ccc; +} + +div.dashboard-widget-error { + background-color: #c43; +} + +div.dashboard-widget-notice { + background-color: #F0F6FB; +} + +div.dashboard-widget-submit, ul.widget-control-list div.widget-control-actions { + border-top-color: #ccc; +} + +input.disabled, textarea.disabled { + background-color: #ccc; +} + +li.widget-list-control-item h4.widget-title a:hover, .submit a, #user_info a, #dashmenu a:hover, #footer a, #upload-menu li a.upload-tab-link, li.widget-list-control-item h4.widget-title a, +#dragHelper li.widget-list-control-item h4.widget-title a, +#draghelper li.widget-list-control-item h4.widget-title a:visited, .login #backtoblog a:hover { + color: #fff; +} + +ul#category-tabs li.ui-tabs-selected, li.widget-list-control-item, div.nav, .tablenav, .submitbox, h3.dashboard-widget-title, h3.dashboard-widget-title span, h3.dashboard-widget-title small, ul.view-switch li.current, .form-table tr, #poststuff h3, .login form { + background-color: #cfebf7; +} + +div.ui-tabs-panel { + border-color: #cfebf7; +} + +select { + background-color: #fff; + border-color: #ddd; +} + +strong .post-com-count span { + background-color: #2583ad; +} + +.button-secondary, #quicktags, #login form .submit input { + background-color: #83b4d5 !important; +} + +ul#widget-list li.widget-list-item h4.widget-title { + background-color: #f0f0f0; + color: #000; +} + +ul.widget-control-list .sorthelper { + background-color: #ccf3fa; +} + +.ac_match, .subsubsub a.current, h2 { + color: #000; +} + +.ac_over { + background-color: #f0f0b8; +} + +.ac_results { + background-color: #fff; + border-color: #808080; +} + +.ac_results li { + color: #101010; +} + +.alternate { + background-color: #f9f9f9; +} + +.available-theme a.screenshot { + background-color: #f1f1f1; + border-color: #ccc; +} + +.bar { + background-color: #e8e8e8; + border-right-color: #99d; +} + +.describe { + border-top-color: #d0d0d0; +} + +.error, #login #login_error { + background-color: #ffebe8; + border-color: #c00; +} + +.error a { + color: #c00; +} + +.form-invalid { + background-color: #ffebe8 !important; +} + +.form-invalid input { + border-color: #c00 !important; +} + +.form-table input, .form-table textarea { + border-color: #c6d9e9; +} + +.form-table td, .form-table th { + border-bottom-color: #fff; +} + +.highlight { + background-color: #cfebf7; + color: #d54e21; +} + +.howto, .nonessential, #sidemenu, #edit-slug-box, .form-input-tip, #dashboard_primary span.rss-date, .subsubsub, #dashboard_secondary div.dashboard-widget-content ul li a cite { + color: #999; +} + +#dashmenu a { + color: #88b4d7; +} + +.media-item { + border-bottom-color: #d0d0d0; +} + +.media-upload-form label.form-help, td.help { + color: #9a9a9a; +} + +.page-numbers { + background-color: #fff; + border-color: #fff; +} + +.page-numbers.current { + background-color: #328ab2; + border-color: #328ab2; + color: #fff; +} + +.post-com-count { + background-image: url(../images/bubble_bg.gif); + color: #fff; +} + +.post-com-count span { + background-color: #bbb; + color: #fff; +} + +.post-com-count:hover span { + background-color: #d54e21; +} + +.quicktags, .search { + background-color: #ccc; + color: #000; +} + +.side-info h5, .bordertitle { + border-bottom-color: #dadada; +} + +.side-info ul { + color: #666; +} + +.submit input, .button, .button-secondary, #login form .submit input, div.dashboard-widget-submit input { + background-color: #e5e5e5; + color: #246; + border-color: #a3a3a3; +} + +.tablenav .button-secondary { + border-color: #5396c5; +} + +.submit input:hover, .button:hover { + border-color: #535353; +} + +.submit input:hover, .button:hover, .button-secondary:hover, #wphead #viewsite a:hover, #adminmenu a:hover, #sidemenu a:hover, #submenu a.current, #submenu a:hover, .submitbox #previewview a:hover, #the-comment-list .comment a:hover, #rightnow a:hover, a:hover, .subsubsub a:hover, .subsubsub a.current:hover, #login form .submit input:hover, div.dashboard-widget-submit input:hover { + color: #d54e21; +} + +.button-secondary:hover, #login form .submit input:hover { + border-color: #328ab2; +} + +.submitbox #autosave .error, ul.view-switch li.current a { + color: #333; +} + +.submitbox #previewview { + background-color: #5488af; +} + +.submitbox #previewview a, #rightnow .rbutton { + background-color: #ebebeb; + color: #264761; +} + +.submitbox .submit { + background-color: #464646; + color: #ccc; +} + +.submitbox .submitdelete { + border-bottom-color: #999; +} + +.submitbox .submitdelete:hover { + color: #fff; + background-color: #f00; + border-bottom-color: #f00; +} + +.tablenav .dots { + background-color: #cfebf7; + border-color: #cfebf7; +} + +.tablenav .next, .tablenav .prev{ + background-color: #cfebf7; + border-bottom-color: #cfebf7; + border-color: #cfebf7; + color: #2583ad; +} + +.tablenav .next:hover, .tablenav .prev:hover { + border-bottom-color: #d54e21; + border-color: #cfebf7; + color: #d54e21; +} + +.updated, .login #login_error, .login .message { + background-color: #ffffe0; + border-color: #e6db55; +} + +.updated a { + border-bottom-color: #2583ad; +} + +.widefat td, .widefat th, div#available-widgets-filter, ul#widget-list li.widget-list-item, .commentlist li { + border-bottom-color: #ccc; +} + +.widefat thead, .thead { + background-color: #464646; + color: #d7d7d7; +} + +.widget-control-save, .widget-control-remove { + background-color: #83b4d5; + color: #246; +} + +.wrap h2 { + border-bottom-color: #dadada; + color: #5a5a5a; +} + +#poststuff #edButtonPreview, #poststuff #edButtonHTML, #the-comment-list p.comment-author strong a, a { + color: #2e7ca0; +} + +#adminmenu a { + color: #cfebf6; +} + +#submenu a { + color: #2782af +} +/* Because we don't want visited on these links */ +#adminmenu a.current, #sidemenu a.current { + background-color: #fff; + border-color: #c6d9e9; + border-bottom-color: #fff; + color: #d54e21; + font-weight: bold; +} + +#adminmenu li a #awaiting-mod { + background-image: url(../images/comment-stalk-classic.gif); +} + +#adminmenu li a #awaiting-mod span { + background-color: #d54e21; + color: #fff; +} + +#rightnow .reallynow { + background-color: #114973; + color: #fff; +} + + +#adminmenu li a:hover #awaiting-mod span { + background-color: #07273E; +} + +#adminmenu, div#media-upload-header { + background-color: #14568a; + border-bottom-color: #c6d9e9; +} + +#currenttheme img { + border-color: #666; +} + +#current-widgets .drop-widget-here { + background-color: #ffc; +} + +#dashboard_secondary div.dashboard-widget-content ul li a { + background-color: #f9f9f9; +} + +input.readonly { + background-color: #ddd; +} + +#dashmenu a.current { + background-color: #14568a; + color: #cfebf6; +} + +#dragHelper h4.widget-title, li.widget-list-control-item h4, #dragHelper li.widget-list-control-item h4 { + background-color: #2683ae; + color: #fff; +} + +#ed_toolbar input { + background: url( ../images/fade-butt.png ) #fff repeat-x 0 -2px; +} + +#editable-post-name { + background-color: #fffbcc; +} + +#edit-slug-box strong, .login #nav a { + color: #777; +} + +#edit-slug-buttons a.save { + background-color: #ebebeb; +} + +#footer { + background: url(../images/logo-ghost.png) #464646 no-repeat 20px 10px; + color: #999; +} + +#media-items { + border-color: #c0c0c0; +} + +#pass-strength-result { + background-color: #e3e3e3; + border-color: #000; +} + +#pass-strength-result.bad { + background-color: #ffeff7; + border-color: #c69; +} + +#pass-strength-result.good { + background-color: #effff4; + border-color: #66cc87; +} + +#pass-strength-result.short { + background-color: #e3e3e3; +} + +#pass-strength-result.strong { + background-color: #59ef86; + border-color: #319f52; +} + +#plugins .active, .checkbox, .side-info, #your-profile #rich_editing { + background-color: #fff; +} + +#plugins .togl { + border-right-color: #ccc; +} + +#plugins tr, #the-comment-list .unapproved { + background-color: #f0f0f0; +} + +#poststuff #editor-toolbar .active { + background-color: #83b4d5; + color: #333; +} + +#poststuff .closed .togbox { + background-color: #2583ad; + background-image: url(../images/toggle-arrow.gif); +} + +#poststuff .postbox, #titlediv, #poststuff .postarea, #poststuff .stuffbox { + border-color: #ebebeb; + border-right-color: #ccc; + border-bottom-color: #ccc; +} + +#poststuff .togbox { + background-color: #b2b2b2; + background-image: url(../images/toggle-arrow.gif); +} + +#quicktags #ed_link { + color: #00f; +} + +#rightnow .youhave { + background-color: #f0f6fb; +} + +#rightnow a { + color: #448abd; +} + +#sidemenu a { + background-color: #14568a; + border-bottom-color: #c6d9e9; + border-top-color: #14568a; + color: #cfebf6; +} + +#tagchecklist span a { + background: url(../images/xit.gif) no-repeat; +} + +#tagchecklist span a:hover { + background: url(../images/xit.gif) no-repeat -10px 0; +} + +#the-comment-list .comment a { + border-bottom-color: #ababab; + color: #666; +} + +#update-nag a:link, .plugin-update a:link { + color: #036; +} + +#update-nag, .plugin-update { + background-color: #fffeeb; + border-bottom-color: #ccc; + border-top-color: #ccc; + color: #cfebf6; +} + +#upload-files a.file-link { + background-color: #d1e2ef; +} + +#upload-file-view a img { + border-bottom-color: #69c; +} + +#upload-menu li #current-tab-nav, #upload-file { + background-color: #f9fcfe; +} + +#upload-menu li span a.page-numbers { + color: #00019b; +} + +#upload-menu li.current { + border-right-color: #448abd; + color: #000; +} + +#upload-menu li.current a.upload-tab-link, #upload-menu li a:hover { + background-color: #f9fcfe; + color: #000; +} + +#upload-menu, #upload-menu li { + border-top-color: #247fab; +} + +#user_info, .login #backtoblog a { + color: #ccc; +} + +#wphead { + background-color: #14568a; +} + +#wphead, body.login { + border-top-color: #07273e; +} + +#wphead #viewsite a { + background-color: #94acc1; + color: white; + border-color: #94acc1; +} + +#wphead #viewsite a:hover { + color: #246; +} + +#wphead h1, #dashmenu a.current:hover { + color: #cfebf6; +} + +div#media-upload-error, .file-error, abbr.required, .widget-control-remove:hover, .delete:hover { + color: #f00; +} + +#media-upload a.delete { + color: #888; +} + + +/* TinyMCE */ +.wp_themeSkin *, +.wp_themeSkin a:hover, +.wp_themeSkin a:link, +.wp_themeSkin a:visited, +.wp_themeSkin a:active { + color: #000; +} + +/* Containers */ +.wp_themeSkin table { + background: #83B4D5; +} + +.wp_themeSkin iframe { + background: #fff; +} + +/* Layout */ +.wp_themeSkin .mceStatusbar { + color:#000; + background-color: #eaf3fa; +} + +/* Button */ +.wp_themeSkin .mceButton { + background-color: #e9e8e8; + border-color: #83B4D5; +} + +.wp_themeSkin a.mceButtonEnabled:hover, +.wp_themeSkin a.mceButtonActive, +.wp_themeSkin a.mceButtonSelected { + background-color: #d6d8da; + border-color: #7789ba !important; +} + +.wp_themeSkin .mceButtonDisabled { + border-color: #83B4D5 !important; +} + +/* ListBox */ +.wp_themeSkin .mceListBox .mceText, +.wp_themeSkin .mceListBox .mceOpen { + border-color: #83B4D5; + background-color: #e9e8e8; +} + +.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen, +.wp_themeSkin .mceListBoxHover .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceText { + border-color: #7789ba !important; + background-color: #d6d8da; +} + +.wp_themeSkin table.mceListBoxEnabled:hover .mceText, +.wp_themeSkin .mceListBoxHover .mceText { + border-color: #7789ba !important; +} + +.wp_themeSkin select.mceListBox { + border-color: #b3c7e1; + background-color: #fff; +} + +/* SplitButton */ +.wp_themeSkin .mceSplitButton a.mceAction, +.wp_themeSkin .mceSplitButton a.mceOpen { + background-color: #e9e8e8; + border-color: #83B4D5; +} + +.wp_themeSkin .mceSplitButton a.mceOpen:hover, +.wp_themeSkin .mceSplitButtonSelected a.mceOpen, +.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction, +.wp_themeSkin .mceSplitButton a.mceAction:hover { + background-color: #d6d8da; + border-color: #7789ba !important; +} + +.wp_themeSkin .mceSplitButtonActive { + background-color: #d6d8da; +} + +/* ColorSplitButton */ +.wp_themeSkin div.mceColorSplitMenu table { + background-color: #ebeaeb; + border-color: #808080; +} + +.wp_themeSkin .mceColorSplitMenu a { + border-color: #808080; +} + +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors { + border-color: #fff; +} + +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover { + border-color: #0A246A; + background-color: #B6BDD2; +} + +.wp_themeSkin a.mceMoreColors:hover { + border-color: #0A246A; +} + +/* Menu */ +.wp_themeSkin .mceMenu { + border-color: #ddd; +} + +.wp_themeSkin .mceMenu table { + background-color: #ebeaeb; +} + +.wp_themeSkin .mceMenu .mceText { + color: #000; +} + +.wp_themeSkin .mceMenu .mceMenuItemEnabled a:hover, +.wp_themeSkin .mceMenu .mceMenuItemActive { + background-color: #83B4D5; +} +.wp_themeSkin td.mceMenuItemSeparator { + background-color: #aaa; +} +.wp_themeSkin .mceMenuItemTitle a { + background-color: #ccc; + border-bottom-color: #aaa; +} +.wp_themeSkin .mceMenuItemTitle span.mceText { + color: #000; +} +.wp_themeSkin .mceMenuItemDisabled .mceText { + color: #888; +} + +/* pop-up */ +.clearlooks2 .mceTop .mceLeft, .clearlooks2 .mceTop .mceRight { + background-color: #cee1ef; + border-color: #c6d9e9; +} + +.clearlooks2 .mceFocus .mceTop .mceLeft, .clearlooks2 .mceFocus .mceTop .mceRight { + background-color: #5488AF; + border-color: #464646; +} + +#editorcontainer { + border-color: #ccc; +} + +#poststuff #titlewrap { + border-color: #ccc; +} diff --git a/wp-admin/css/colors-fresh.css b/wp-admin/css/colors-fresh.css new file mode 100644 index 0000000..823ba46 --- /dev/null +++ b/wp-admin/css/colors-fresh.css @@ -0,0 +1,681 @@ +a.page-numbers:hover { + border-color: #999; +} + +body { + background-color: #fff; + color: #333; +} + +body > #upload-menu { + border-bottom-style: #fff; +} + +div#current-widgets, #postcustomstuff table, #your-profile fieldset, a.page-numbers, #rightnow, div.dashboard-widget, .widefat { + border-color: #ccc; +} + +div.dashboard-widget-error { + background-color: #c43; +} + +div.dashboard-widget-notice { + background-color: #cfe1ef; +} + +div.dashboard-widget-submit, ul.widget-control-list div.widget-control-actions { + border-top-color: #ccc; +} + +div.ui-tabs-panel { + border-color: #cee1ef; +} + +input.disabled, textarea.disabled { + background-color: #ccc; +} + +li.widget-list-control-item h4.widget-title a:hover, .submit a, #user_info a, #dashmenu a:hover, #footer a, #upload-menu li a.upload-tab-link, li.widget-list-control-item h4.widget-title a, +#dragHelper li.widget-list-control-item h4.widget-title a, +#draghelper li.widget-list-control-item h4.widget-title a:visited, .login #backtoblog a:hover { + color: #fff; +} + +li.widget-list-control-item, div.nav, .tablenav, .submitbox, h3.dashboard-widget-title, h3.dashboard-widget-title span, h3.dashboard-widget-title small, ul.view-switch li.current, .form-table tr, #poststuff h3, .login form { + background-color: #eaf3fa; +} + +select { + background-color: #fff; + border-color: #ddd; +} + +strong .post-com-count span { + background-color: #2583ad; +} + +ul#category-tabs li.ui-tabs-selected, .button-secondary, #quicktags, #login form .submit input { + background-color: #cee1ef !important; +} + +ul#widget-list li.widget-list-item h4.widget-title { + background-color: #f0f0f0; + color: #000; +} + +ul.widget-control-list .sorthelper { + background-color: #ccf3fa; +} + +.ac_match, .subsubsub a.current, h2 { + color: #000; +} + +.ac_over { + background-color: #f0f0b8; +} + +.ac_results { + background-color: #fff; + border-color: #808080; +} + +.ac_results li { + color: #101010; +} + +.alternate { + background-color: #f9f9f9; +} + +.available-theme a.screenshot { + background-color: #f1f1f1; + border-color: #ccc; +} + +.bar { + background-color: #e8e8e8; + border-right-color: #99d; +} + +.describe { + border-top-color: #d0d0d0; +} + +.error, #login #login_error { + background-color: #ffebe8; + border-color: #c00; +} + +.error a { + color: #c00; +} + +.form-invalid { + background-color: #ffebe8 !important; +} + +.form-invalid input { + border-color: #c00 !important; +} + +.form-table input, .form-table textarea { + border-color: #c6d9e9; +} + +.form-table td, .form-table th { + border-bottom-color: #fff; +} + +.highlight { + background-color: #e4f2fd; + color: #d54e21; +} + +.howto, .nonessential, #dashmenu a, #sidemenu, #edit-slug-box, .form-input-tip, #dashboard_primary span.rss-date, .subsubsub, #dashboard_secondary div.dashboard-widget-content ul li a cite { + color: #999; +} + +.media-item { + border-bottom-color: #d0d0d0; +} + +.media-upload-form label.form-help, td.help { + color: #9a9a9a; +} + +.page-numbers { + background-color: #fff; + border-color: #fff; +} + +.page-numbers.current { + background-color: #328ab2; + border-color: #328ab2; + color: #fff; +} + +.post-com-count { + background-image: url(../images/bubble_bg.gif); + color: #fff; +} + +.post-com-count span { + background-color: #bbb; + color: #fff; +} + +.post-com-count:hover span { + background-color: #d54e21; +} + +.quicktags, .search { + background-color: #ccc; + color: #000; +} + +.side-info h5, .bordertitle { + border-bottom-color: #dadada; +} + +.side-info ul { + color: #666; +} + +.submit input, .button, .button-secondary, #login form .submit input, div.dashboard-widget-submit input { + background-color: #e5e5e5; + color: #246; + border-color: #a3a3a3; +} + +.submit input:hover, .button:hover { + border-color: #535353; +} + +.submit input:hover, .button:hover, .button-secondary:hover, #wphead #viewsite a:hover, #adminmenu a:hover, #sidemenu a:hover, #submenu a.current, #submenu a:hover, .submitbox #previewview a:hover, #the-comment-list .comment a:hover, #rightnow a:hover, a:hover, .subsubsub a:hover, .subsubsub a.current:hover, #login form .submit input:hover, div.dashboard-widget-submit input:hover { + color: #d54e21; +} + +.button-secondary:hover, #login form .submit input:hover { + border-color: #328ab2; +} + +.submitbox #autosave .error, ul.view-switch li.current a { + color: #333; +} + +.submitbox #previewview { + background-color: #2683ae; +} + +.submitbox #previewview a, #rightnow .rbutton { + background-color: #ebebeb; + color: #264761; +} + +.submitbox .submit { + background-color: #464646; + color: #ccc; +} + +.submitbox .submitdelete { + border-bottom-color: #999; +} + +.submitbox .submitdelete:hover { + color: #fff; + background-color: #f00; + border-bottom-color: #f00; +} + +.tablenav .dots { + background-color: #e4f2fd; + border-color: #e4f2fd; +} + +.tablenav .next, .tablenav .prev{ + background-color: #e4f2fd; + border-bottom-color: #2583ad; + border-color: #e4f2fd; + color: #2583ad; +} + +.tablenav .next:hover, .tablenav .prev:hover { + border-bottom-color: #d54e21; + border-color: #e4f2fd; + color: #d54e21; +} + +.updated, .login #login_error, .login .message { + background-color: #ffffe0; + border-color: #e6db55; +} + +.updated a { + border-bottom-color: #2583ad; +} + +.widefat td, .widefat th, div#available-widgets-filter, ul#widget-list li.widget-list-item, .commentlist li { + border-bottom-color: #ccc; +} + +.widefat thead, .thead { + background-color: #464646; + color: #d7d7d7; +} + +.widget-control-save, .widget-control-remove { + background-color: #cee1ef; + color: #246; +} + +.wrap h2 { + border-bottom-color: #dadada; + color: #666; +} + +#adminmenu a, #submenu a, #poststuff #edButtonPreview, #poststuff #edButtonHTML, #the-comment-list p.comment-author strong a, a { + color: #2583ad; +} + +/* Because we don't want visited on these links */ +#adminmenu a.current, #sidemenu a.current { + background-color: #fff; + border-color: #c6d9e9; + border-bottom-color: #fff; + color: #d54e21; +} + +#adminmenu li a #awaiting-mod { + background-image: url(../images/comment-stalk-fresh.gif); +} + +#adminmenu li a #awaiting-mod span, #rightnow .reallynow { + background-color: #d54e21; + color: #fff; +} + +#adminmenu li a:hover #awaiting-mod span { + background-color: #264761; +} + +#adminmenu, div#media-upload-header { + background-color: #e4f2fd; + border-bottom-color: #c6d9e9; +} + +#currenttheme img { + border-color: #666; +} + +#current-widgets .drop-widget-here { + background-color: #ffc; +} + +#dashboard_secondary div.dashboard-widget-content ul li a { + background-color: #f9f9f9; +} + +input.readonly { + background-color: #ddd; +} + +#dashmenu a.current { + background-color: #e4f2fd; + color: #555; +} + +#dragHelper h4.widget-title, li.widget-list-control-item h4, #dragHelper li.widget-list-control-item h4 { + background-color: #2683ae; + color: #fff; +} + +#ed_toolbar input { + background: url( ../images/fade-butt.png ) #fff repeat-x 0 -2px; +} + +#editable-post-name { + background-color: #fffbcc; +} + +#edit-slug-box strong, .login #nav a { + color: #777; +} + +#edit-slug-buttons a.save { + background-color: #ebebeb; +} + +#footer { + background: url(../images/logo-ghost.png) #464646 no-repeat 20px 10px; + color: #999; +} + +#media-items { + border-color: #c0c0c0; +} + +#pass-strength-result { + background-color: #e3e3e3; + border-color: #000; +} + +#pass-strength-result.bad { + background-color: #ffeff7; + border-color: #c69; +} + +#pass-strength-result.good { + background-color: #effff4; + border-color: #66cc87; +} + +#pass-strength-result.short { + background-color: #e3e3e3; +} + +#pass-strength-result.strong { + background-color: #59ef86; + border-color: #319f52; +} + +#plugins .active, .checkbox, .side-info, #your-profile #rich_editing { + background-color: #fff; +} + +#plugins .togl { + border-right-color: #ccc; +} + +#plugins tr, #the-comment-list .unapproved { + background-color: #f0f0f0; +} + +#poststuff #editor-toolbar .active { + background-color: #cee1ef; + color: #333; +} + +#poststuff .closed .togbox { + background-color: #2583ad; + background-image: url(../images/toggle-arrow.gif); +} + +#poststuff .postbox, #titlediv, #poststuff .postarea, #poststuff .stuffbox { + border-color: #ebebeb; + border-right-color: #ccc; + border-bottom-color: #ccc; +} + +#poststuff .togbox { + background-color: #b2b2b2; + background-image: url(../images/toggle-arrow.gif); +} + +#quicktags #ed_link { + color: #00f; +} + +#rightnow .youhave { + background-color: #f0f6fb; +} + +#rightnow a { + color: #448abd; +} + +#sidemenu a { + background-color: #e4f2fd; + border-bottom-color: #c6d9e9; + border-top-color: #e4f2fd; +} + +#tagchecklist span a { + background: url(../images/xit.gif) no-repeat; +} + +#tagchecklist span a:hover { + background: url(../images/xit.gif) no-repeat -10px 0; +} + +#the-comment-list .comment a { + border-bottom-color: #ababab; + color: #666; +} + +#update-nag a:link, .plugin-update a:link { + color: #036; +} + +#update-nag, .plugin-update { + background-color: #fffeeb; + border-bottom-color: #ccc; + border-top-color: #ccc; + color: #555; +} + +#upload-files a.file-link { + background-color: #d1e2ef; +} + +#upload-file-view a img { + border-bottom-color: #69c; +} + +#upload-menu li #current-tab-nav, #upload-file { + background-color: #f9fcfe; +} + +#upload-menu li span a.page-numbers { + color: #00019b; +} + +#upload-menu li.current { + border-right-color: #448abd; + color: #000; +} + +#upload-menu li.current a.upload-tab-link, #upload-menu li a:hover { + background-color: #f9fcfe; + color: #000; +} + +#upload-menu, #upload-menu li { + border-top-color: #247fab; +} + +#user_info, .login #backtoblog a, .curtime { + color: #ccc; +} + +#wphead { + background-color: #e4f2fd; +} + +#wphead, body.login { + border-top-color: #464646; +} + +#wphead #viewsite a { + background-color: #c6d9e9; + color: #246; + border-color: #94acc1; +} + +#wphead #viewsite a:hover { + border-color: #246; +} + +#wphead h1, #dashmenu a.current:hover, #login form input { + color: #555; +} + +div#media-upload-error, .file-error, abbr.required, .widget-control-remove:hover, .delete:hover { + color: #f00; +} + +#media-upload a.delete { + color: #888; +} + +/* TinyMCE */ +.wp_themeSkin *, +.wp_themeSkin a:hover, +.wp_themeSkin a:link, +.wp_themeSkin a:visited, +.wp_themeSkin a:active { + color: #000; +} + +/* Containers */ +.wp_themeSkin table { + background: #cee1ef; +} + +.wp_themeSkin iframe { + background: #fff; +} + +/* Layout */ +.wp_themeSkin .mceStatusbar { + color:#000; + background-color: #eaf3fa; +} + +/* Button */ +.wp_themeSkin .mceButton { + background-color: #e9e8e8; + border-color: #abc0fb; +} + +.wp_themeSkin a.mceButtonEnabled:hover, +.wp_themeSkin a.mceButtonActive, +.wp_themeSkin a.mceButtonSelected { + background-color: #d6d8da; + border-color: #7789ba !important; +} + +.wp_themeSkin .mceButtonDisabled { + border-color: #bdd !important; +} + +/* ListBox */ +.wp_themeSkin .mceListBox .mceText, +.wp_themeSkin .mceListBox .mceOpen { + border-color: #abc0fb; + background-color: #e9e8e8; +} + +.wp_themeSkin table.mceListBoxEnabled:hover .mceOpen, +.wp_themeSkin .mceListBoxHover .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceOpen, +.wp_themeSkin .mceListBoxSelected .mceText { + border-color: #7789ba !important; + background-color: #d6d8da; +} + +.wp_themeSkin table.mceListBoxEnabled:hover .mceText, +.wp_themeSkin .mceListBoxHover .mceText { + border-color: #7789ba !important; +} + +.wp_themeSkin select.mceListBox { + border-color: #b3c7e1; + background-color: #fff; +} + +/* SplitButton */ +.wp_themeSkin .mceSplitButton a.mceAction, +.wp_themeSkin .mceSplitButton a.mceOpen { + background-color: #e9e8e8; + border-color: #abc0fb; +} + +.wp_themeSkin .mceSplitButton a.mceOpen:hover, +.wp_themeSkin .mceSplitButtonSelected a.mceOpen, +.wp_themeSkin table.mceSplitButtonEnabled:hover a.mceAction, +.wp_themeSkin .mceSplitButton a.mceAction:hover { + background-color: #d6d8da; + border-color: #7789ba !important; +} + +.wp_themeSkin .mceSplitButtonActive { + background-color: #d6d8da; +} + +/* ColorSplitButton */ +.wp_themeSkin div.mceColorSplitMenu table { + background-color: #ebeaeb; + border-color: #808080; +} + +.wp_themeSkin .mceColorSplitMenu a { + border-color: #808080; +} + +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors { + border-color: #fff; +} + +.wp_themeSkin .mceColorSplitMenu a.mceMoreColors:hover { + border-color: #0A246A; + background-color: #B6BDD2; +} + +.wp_themeSkin a.mceMoreColors:hover { + border-color: #0A246A; +} + +/* Menu */ +.wp_themeSkin .mceMenu { + border-color: #ddd; +} + +.wp_themeSkin .mceMenu table { + background-color: #ebeaeb; +} + +.wp_themeSkin .mceMenu .mceText { + color: #000; +} + +.wp_themeSkin .mceMenu .mceMenuItemEnabled a:hover, +.wp_themeSkin .mceMenu .mceMenuItemActive { + background-color: #CEE1EF; +} +.wp_themeSkin td.mceMenuItemSeparator { + background-color: #aaa; +} +.wp_themeSkin .mceMenuItemTitle a { + background-color: #ccc; + border-bottom-color: #aaa; +} +.wp_themeSkin .mceMenuItemTitle span.mceText { + color: #000; +} +.wp_themeSkin .mceMenuItemDisabled .mceText { + color: #888; +} + +/* pop-up */ +.clearlooks2 .mceTop .mceLeft, .clearlooks2 .mceTop .mceRight { + background-color: #cee1ef; + border-color: #c6d9e9; +} + +.clearlooks2 .mceFocus .mceTop .mceLeft, .clearlooks2 .mceFocus .mceTop .mceRight { + background-color: #2683ae; + border-color: #464646; +} + +#editorcontainer { + border-color: #ccc; +} + +#poststuff #titlewrap { + border-color: #ccc; +} + +.curtime { + color: #666; +}
\ No newline at end of file diff --git a/wp-admin/css/dashboard.css b/wp-admin/css/dashboard.css new file mode 100644 index 0000000..003e8e3 --- /dev/null +++ b/wp-admin/css/dashboard.css @@ -0,0 +1,283 @@ +/* Right Now */ + +#rightnow { + border-width: 1px; + border-style: solid; + padding: 2px; + margin-top: 10px; + margin-right: 7px; +} + +#rightnow .reallynow { + padding: 6px; + font-size: 15px; + line-height: 2; + margin: 0; +} + +#rightnow .rbutton { + font-weight: normal; + padding: 6px; + border-bottom: none; + -moz-border-radius: 2px; + -khtml-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + text-decoration: none; +} + +#rightnow .reallynow span { + display: block; + text-align: left; + float: left; + padding: 0 6px; +} + +#rightnow .reallynow a { + display: block; + text-align: right; + float: right; + padding: 0 6px; + font-size: 14px; + margin: 1px 6px 0 0; +} + +#rightnow .youhave { + font-size: 14px; + padding: 10px; +} + +#rightnow h3, #rightnow p { + padding: 0 10px; +} + +#rightnow a { + font-weight: bold; +} + +/* Widgets */ + +div#dashboard-widgets-wrap { + margin-top: -20px; + margin-right: -13px; /* 20 (div.dashboard-widget margin-right) - 7 (#rightnow margin-right) */ +} + +div#dashboard-widgets { + width: 100%; + padding-right: 7px; /* (#rightnow margin-right) */ +} + +div.dashboard-widget-holder { + margin-top: 20px; + width: 50%; + float: left; +} + +div.dashboard-widget-holder.third { + width: 33.3%; +} + +div.dashboard-widget-holder.fourth { + width: 25%; +} + +div.dashboard-widget-holder.full { + width: 100%; +} + +div.dashboard-widget-holder.double div.dashboard-widget { + height: 52em; + padding-bottom: 28px /* lame */ +} + +div.dashboard-widget { + position: relative; + margin-right: 20px; + border-width: 1px; + border-style: solid; + padding: 2px; + height: 27em; + overflow: auto; + font-size: 11px; +} + +h3.dashboard-widget-title { + margin: 0; + padding: 0 7px; + font-size: 14px; + line-height: 2; +} + +h3.dashboard-widget-title span { + display: block; + text-align: left; + float: left; +} + +h3.dashboard-widget-title small { + display: block; + text-align: right; + float: right; + font-size: 75%; + line-height: 2.67; /* math: it works, bitches */ +} + +h3.dashboard-widget-title img.rss-icon { + vertical-align: middle; + margin: .5em 0; +} + +div.dashboard-widget-notice { + padding: 0 14px; + font-size: 1.2em; + line-height: 2; +} + +div.dashboard-widget-error { + padding: 0 20px; + font-size: 1.2em; + line-height: 2; +} + +div.dashboard-widget-content { + padding: 10px 15px; +} + +div.dashboard-widget-submit { + border-top: 1px solid #ccc; + padding: 1em 0 0 0; + margin: 10px 0 0 0; +} +div.dashboard-widget-submit input { + font-family: "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif; + padding: 4px 6px; + border: none; + font-size: 13px; + -moz-border-radius: 3px; + -khtml-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + cursor: pointer; + text-decoration: none; +} + +div.dashboard-widget-content ul, div.dashboard-widget-content ol, div.dashboard-widget-content dl { + margin: 0; + text-indent: 0; + padding-left: 15px; +} +div.dashboard-widget-content li { + margin: .5em 0 1em; +} + +div.dashboard-widget-content blockquote { + margin: -1em 0; +} + +div#dashboard_recent_comments p { + font-size: 14px; +} + +div.dashboard-widget-content p.comment-meta { + font-size: 11px !important; +} + +#dashboard_secondary div.dashboard-widget { + height: auto; +} + +#dashboard_secondary div.dashboard-widget-content ul { + list-style: none; + padding: 0; +} + +#dashboard_secondary div.dashboard-widget-content ul li { + display: block; + width: 19.95%; + padding-bottom: 10px; + margin: 0; + float: left; + font-size: 95%; +} + +#dashboard_secondary div.dashboard-widget-content { + margin: 10px 5px; + padding: 0; +} + +#dashboard_secondary div.dashboard-widget-content ul li .post { + display:block; + font-family:Georgia,"Times New Roman",Times,serif; + font-size:18px; + line-height: 1.2em; + height:90px; + overflow:hidden; +} + +#dashboard_secondary div.dashboard-widget-content ul li a { + display: block; + height:100%; + overflow:hidden; + margin: 5px 10px; + text-decoration: none; + padding: .5em; + border-right: 1px solid #dadada; + border-bottom: 1px solid #dadada; +} + +#dashboard_secondary div.dashboard-widget-content ul li a cite { + display: block; + font-family: "Lucida Sans", "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif; +} + +#dashboard-widgets .widget_rss ul { + list-style: none; + padding: 0; +} + +#dashboard-widgets .widget_rss ul li { + clear: both; +} + +#dashboard-widgets .widget_rss ul li span.rss-date { + float: left; + margin: 0; +} + +#dashboard-widgets .widget_rss ul li a { + float: left; + margin: 0 .5em .2em 0; + font-weight: bold; +} + +#dashboard-widgets .widget_rss ul li div { + clear: both; + line-height: 1.5em; +} + +#dashboard_primary a.rsswidget, #dashboard_plugins h5 { + font-size: 14px; +} + +#dashboard_primary span.rss-date { + font-size: 14px; +} + +#dashboard_plugins h4 { + font-size: 1em; + margin: 0 0 .1em; +} + +#dashboard_plugins h5 { + margin: 0; + display: inline; + line-height: 1.4em; +} + +#dashboard_plugins p { + margin: 0 0 1em; + line-height: 1.5em; +} + +.widget-loading { +} diff --git a/wp-admin/css/global.css b/wp-admin/css/global.css new file mode 100644 index 0000000..5bd9e2f --- /dev/null +++ b/wp-admin/css/global.css @@ -0,0 +1,126 @@ +/* styles for use by people extending the WordPress interface */ + + +body { + margin: 0; + padding: 0; +} + +body, td { + font: 13px "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif; +} + +form, label input { margin: 0; padding: 0; } + +img { border: 0; } + +label { cursor: pointer; } + +li, dd { margin-bottom: 6px; } + +p, li, dl, dd, dt { line-height: 140%; } + +textarea, input, select { + font: 13px Verdana, Arial, Helvetica, sans-serif; + margin: 1px; + padding: 3px; +} + +.alignleft { float: left; } + +.alignright { float: right; } + + +.clear { clear: both; height: 2px; } + +.hidden { display: none; } + +.subsubsub { + list-style: none; + margin: 15px 0 10px 0; + padding: 0; + white-space: nowrap; + font-size: 12px; +} + +.subsubsub a { line-height: 200%; padding: 3px; text-decoration: none; } + +.subsubsub a.current { font-weight: bold; background: none; border: none;} + +.subsubsub li { display: inline; margin: 0; padding: 0; } + +.widefat { + border-width: 1px; + border-style: solid; + border-collapse: collapse; + width: 100%; + clear: both; +} + +.widefat a { + text-decoration: none; +} + +.widefat td, .widefat th { + border-bottom-width: 1px; + border-bottom-style: solid; + border-bottom-color: #ccc; + font-size: 12px; + padding: 10px 10px 20px; + vertical-align: text-top; +} + +.widefat th { + padding-bottom: 8px; + padding-top: 10px; + text-align: left; +} + +.widefat .check-column { + text-align: center; + vertical-align: text-top; + width: 3%; +} + +.wrap, .updated, .error { + margin: 0; + margin-left: 15px; + margin-right: 15px; + padding: 0; + max-width: 980px; +} + +.updated, .error { + border-width: 1px; + border-style: solid; + padding: 0 15px; + max-width: 950px; + margin-bottom: 1em; +} + +.wrap .updated, .wrap .error { + margin: auto 0 0; +} + +.updated a, .error a { + text-decoration: underline; +} + +.updated a { + text-decoration: none; + padding-bottom: 2px; +} + +.wrap h2 { + border-bottom-width: 1px; + border-bottom-style: solid; + clear: both; + font: 24px Georgia, "Times New Roman", Times, serif; + margin: 5px 0 0 -4px; + padding: 0; + padding-bottom: 7px; +} + +#timestampdiv { + display: none; +}
\ No newline at end of file diff --git a/wp-admin/css/ie.css b/wp-admin/css/ie.css new file mode 100644 index 0000000..dd7deaa --- /dev/null +++ b/wp-admin/css/ie.css @@ -0,0 +1,58 @@ +/* Fixes for IE bugs */ + +#poststuff .postbox h3 { + padding-left: 23px; +} + +#submenu li a.current { + background:none; + border:none; +} + +* html body.minwidth { + _width: expression(document.documentElement.clientWidth < 810 ? "808px" : "99.9%"); +} + +* html #wpbody { + _width: expression(document.documentElement.clientWidth > 982 ? "980px" : "99.9%"); +} + +* html #poststuff .postarea, * html #poststuff #titlediv { + width: 95%; + margin-left: 3%; +} + +.submitbox { + margin-top: 10px; +} + +* html div.widget-liquid-left-holder, * html div.widget-liquid-right { + display: block; + position: relative; +} + +#wpwrap, #wpcontent, #post, #wrap, #postdivrich, #postdiv, #poststuff, #titlediv, #post-body, #editorcontainer, .tablenav, .widget-control-list { + display: block; + zoom: 100%; +} + +* html #editorcontainer { + padding: 0; +} + +* html #editorcontainer #content { + position: relative; + overflow: auto; + padding: 6px; + margin: auto; + width: 98%; +} + +form#template div { + width: 100%; +} + +#ed_toolbar input { + overflow: visible; + padding: 1px 5px; +} diff --git a/wp-admin/css/login.css b/wp-admin/css/login.css new file mode 100644 index 0000000..92f10bc --- /dev/null +++ b/wp-admin/css/login.css @@ -0,0 +1,74 @@ +* { margin: 0; padding: 0; } + +body { + border-top-width: 30px; + border-top-style: solid; + font: 12px "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif; +} + +form { + margin-left: 8px; + padding: 16px 16px 40px 16px; + font-weight: bold; + -moz-border-radius: 5px; + -khtml-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +form .forgetmenot { font-weight: normal; float: left; margin-bottom: 0;} + +#login form .submit input { + font-family: "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana, sans-serif; + padding: 3px 5px; + border: none; + font-size: 13px; + border-width: 1px; + border-style: solid; + -moz-border-radius: 3px; + -khtml-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + cursor: default; + text-decoration: none; + margin-top: -6px; +} + +form .submit { float: right; } + +form p { margin-bottom: 24px; } + +h1 a { + background: url(../images/logo-login.gif) no-repeat; + width: 292px; + height: 66px; + text-indent: -9999px; + overflow: hidden; + padding-bottom: 15px; + display: block; +} + +#backtoblog a { + position: absolute; + top: 7px; + left: 15px; + text-decoration: none; +} + +#login { width: 292px; margin: 7em auto; } + +#login_error, .message { + margin: 0 0 16px 8px; + border-width: 1px; + border-style: solid; + padding: 12px; +} + +#nav { margin: 0 0 0 8px; padding: 16px; } + +#user_pass, #user_login, #user_email { + font-size: 20px; + width: 97%; + padding: 3px; + margin-right: 6px; +}
\ No newline at end of file diff --git a/wp-admin/css/media.css b/wp-admin/css/media.css new file mode 100644 index 0000000..a5b354e --- /dev/null +++ b/wp-admin/css/media.css @@ -0,0 +1,238 @@ +div#media-upload-header { + margin: 0; + padding: 0 5px; + font-weight: bold; + position: relative; + border-bottom-width: 1px; + border-bottom-style: solid; + height: 2.5em; +} + +ul#sidemenu { + font-weight: normal; + margin: 0 5px; + position: absolute; + left: 0px; + bottom: -1px; +} + +div#media-upload-error { + margin: 1em; + font-weight: bold; +} + +form { + margin: 1em; +} + +#search-filter { + text-align: right; +} + +.media-upload-form label, .media-upload-form legend { + display:block; + font-weight: bold; + margin-bottom: 0.5em; + margin: 0 0 0.5em 0; +} + +th { position: relative; } + +.media-upload-form label.form-help, td.help { + font-style: italic; + font-weight: normal; +} + +.media-upload-form p.help { + margin: 0; + padding: 0; +} + +.media-upload-form fieldset { + width: 100%; + border: none; + text-align: justify; + margin: 0 0 1em 0; + padding: 0; +} + +/* specific to the image upload form */ +.align .field label { + display: inline; + padding: 0 0 0 28px; + margin: 0 1em 0 0; +} +.image-align-none-label { + background: url(../images/align-none.png) no-repeat center left; +} + +.image-align-left-label { + background: url(../images/align-left.png) no-repeat center left; +} + +.image-align-center-label { + background: url(../images/align-center.png) no-repeat center left; +} + +.image-align-right-label { + background: url(../images/align-right.png) no-repeat center left; +} + +#flash-upload-ui, .insert-gallery { + display: none; +} + +tr.image-size label { + display: inline; + margin: 0 1em 0 0; +} +.pinkynail { + max-width: 40px; + max-height: 40px; +} + +.filename { + display: none; +} +button.dismiss { + position: absolute; + top: 5px; + right: 5px; + z-index: 4; +} +.file-error { + margin: 0 0 5px 50px; + font-weight: bold; +} + +.progress { + position: absolute; + top: 0px; + left: 0px; + width: 623px; + height: 36px; +} +.bar { + width: 0px; + height: 100%; + border-right-width: 3px; + border-right-style: solid; +} +.media-item .thumbnail { + max-width: 128px; + max-height: 128px; +} +.media-item .pinkynail { + position: absolute; + top: 2px; + left: 2px; + height: 32px; + max-width: 40px; +} + +tbody.media-item-info tr { + background-color: transparent; +} +tbody.media-item-info th, tbody.media-item-info td { + border: none; + margin: 0; +} + +.form-table tbody.media-item-info { + border: 8px solid #fff; +} + +.describe.startopen, .describe.startclosed { + display: none; +} +abbr.required { + text-decoration: none; + border: none; +} +.describe label { + display: inline; +} +.describe td { + vertical-align: middle; +} +.describe td.A1 { + width: 132px; +} +.describe input[type="text"], .describe textarea { + width: 460px; +} +.describe-toggle-on, .describe-toggle-off { + display: block; + line-height: 36px; + z-index: 2; + position: absolute; + top: 0px; + right: 20px; +} +.describe-toggle-off { + display: none; +} +.clickmask { + background: transparent; + position: absolute; + top: 0px; + left: 0px; + cursor: pointer; + border: none; + z-index: 3; + height: 36px; +} + +.hidden { + height: 0px; + width: 0px; + overflow: hidden; + border: none; +} + +/* Specific to Uploader */ + +#media-upload .media-upload-form p { + margin: 0 1em 1em 0; +} +#media-upload p.help { + font-style: italic; + font-weight: normal; +} +#media-upload tr.image-size td.field { + text-align: center; +} +#media-upload #media-items { + border-width: 1px; + border-style: solid; + border-bottom: none; + width: 623px; +} + +#media-upload .media-item { + border-bottom-width: 1px; + border-bottom-style: solid; + width: 623px; + position: relative; + min-height: 36px; +} +#media-upload .filename { + display: block; + line-height: 36px; + margin-left: 50px; + z-index: 2; +} +#media-upload .describe { + border-top-width: 1px; + border-top-style: solid; + padding: 5px; + width: 100%; + clear: both; +} +#media-upload .describe th.label { + padding-top: .5em; + text-align: left; +} +#media-upload tr.align td.field { + text-align: center; +}
\ No newline at end of file diff --git a/wp-admin/css/theme-editor.css b/wp-admin/css/theme-editor.css new file mode 100644 index 0000000..eaaa946 --- /dev/null +++ b/wp-admin/css/theme-editor.css @@ -0,0 +1,44 @@ +#template textarea { + font-family: 'Courier New', Courier, monospace; + font-size: 12px; + width: 97%; +} + +#template p { + width: 97%; +} + +#templateside { + float: right; + width: 190px; + margin-top:-3.4em; +} + +#templateside h3, #postcustomstuff p.submit { + margin: 0; +} + +#templateside ol, #templateside ul { + list-style: none; + margin: .5em; + padding: 0; +} + +#templateside ol li, #templateside ul li { + margin: 1px 0px; +} + +#themeselector { + padding-right: 5px; + float: right; + position: relative; + bottom: 25px; +} + +.nonessential { + font-size: small; +} + +.highlight { + padding: 1px; +}
\ No newline at end of file diff --git a/wp-admin/css/upload-rtl.css b/wp-admin/css/upload-rtl.css deleted file mode 100644 index dc13a4b..0000000 --- a/wp-admin/css/upload-rtl.css +++ /dev/null @@ -1,12 +0,0 @@ -html { - direction: ltr; - } -#uploadoptions, table { - direction: rtl; - } -td { - padding: 1px 6px 0; - } -.submit { - text-align: left; - }
\ No newline at end of file diff --git a/wp-admin/css/upload.css b/wp-admin/css/upload.css deleted file mode 100644 index 009986c..0000000 --- a/wp-admin/css/upload.css +++ /dev/null @@ -1,204 +0,0 @@ -body { background: #f9fcfe; } - -.upload-file-data { display: none; } - -#upload-menu { - border-top: 2em solid #247fab; - margin: 0; - padding: 0; - height: 0; - list-style: none; - width: 100%; -} - -body > #upload-menu { border-bottom: 7px solid #fff; } - -#upload-menu li { - margin: 0; - position: relative; - top: -2em; - padding-bottom: 5px; - border: none; - border-top: 3px solid #247fab; -} - -#upload-menu li a.upload-tab-link { - margin-left: 0.75em; - padding: 5px 5px 0; - display: block; - float: left; - height: 100%; - text-decoration: none; - border-bottom: none; - color: #fff; -} - -#upload-menu li.current { - border-right: 2px solid #448abd; - color: #000; -} - -#upload-menu li.current a.upload-tab-link, #upload-menu li a:hover { - background: #f9fcfe; - color: #000; -} - -#upload-menu li #current-tab-nav { - background: #f9fcfe; - float: left; - padding: 5px 5px 0 0; - margin-left: -5px; -} - -#upload-menu li span .page-numbers { - padding: 0; - border: none; -} - -#upload-menu li span a.page-numbers { color: #00019b; } -#upload-menu li span a.page-numbers:hover { text-decoration: underline; } - -#upload-content { - position: relative; - clear: both; - margin: 0; - padding: 0; - border: none; - width: 100%; - height: 100%; - background: none; -} - -#upload-file { - margin: 0 auto; - top: 0; - left: 0; - width: 95%; - height: 100%; - background: #f9fcfe; -} - -#upload-file th { - width: 8em; -} - -form#upload-file input, form#upload-file textarea, div#upload-content.upload table { width: 100%; } - -form#upload-file .submit input { width: auto; } - -#upload-file-view { padding: 0 0 0 75px; } - -#file-title { - margin: 0 0 .2em 75px; - padding: 0; - display: block; - font-family: Georgia, "Times New Roman", Times, serif; - font-size: 16px; -} - -h2 { - margin: 0 .2em 0 0; - padding: 0; - display: inline; - border: none; - color: #000; - font-size: 1.4em; - line-height: 1.4em; -} - -.wrap h2 { - margin: .4em 0 .5em; - display: block; - border-bottom: .5em solid #e5f3ff; - color: #333; - font: normal 32px/5px serif; - clear: both; -} - -* html .wrap h2 { - margin-top: 1em; -} - -.back { - display: block; - position: absolute; - left: 14px; - top: 10px; -} - -#upload-files { - list-style-type: none; - margin: 0; - padding: 15px 0 0; -} - -#upload-files li { margin: 0 0 15px 15px; } - -#upload-files a, #upload-file-view a, a.file-link { - border: none; - text-decoration: none; -} - -#upload-file-view a img { padding-bottom: .2em; border-bottom: 1px solid #6699CC; } - -#upload-files a.file-link { - display: block; - width: 130px; - height: 128px; - background-color: rgb(209, 226, 239); - text-align: center; - overflow: hidden; -} - -#upload-files a.text { - padding-top: 40px; - height: 88px; - font-size: 16px; -} - -#upload-files a.file-link.image { - font-size: 2px; - letter-spacing: 0; -} - -#upload-files a.file-link img { vertical-align: middle; } - -#the-attachment-links textarea { - font-size: 10px; - overflow: hidden; -} - -form table { float: none; padding: 0 15px; } - -table { - float: left; - margin: 0; - padding: 0; -} - -th { text-align: right; vertical-align: text-top; } - -tr, td, th { - margin-top: 0; - padding-top: 0; -} - -#uploadoptions th { - width: 80px; -} - -#uploadoptions p { - margin: 0; - padding: 0; -} - -#uploadoptions td { - padding-left: 1em; - line-height: 140%; -} - -#uploadoptions table { - width: 300px; -} - -input.readonly { background-color: #ddd; } diff --git a/wp-admin/edit-attachment-rows.php b/wp-admin/edit-attachment-rows.php new file mode 100644 index 0000000..8eb9066 --- /dev/null +++ b/wp-admin/edit-attachment-rows.php @@ -0,0 +1,138 @@ +<?php if ( ! defined('ABSPATH') ) die(); ?> +<table class="widefat"> + <thead> + <tr> + +<?php $posts_columns = wp_manage_media_columns(); ?> +<?php foreach($posts_columns as $column_display_name) { ?> + <th scope="col"><?php echo $column_display_name; ?></th> +<?php } ?> + + </tr> + </thead> + <tbody id="the-list" class="list:post"> +<?php +$i_post = 0; +if ( have_posts() ) { +$bgcolor = ''; +add_filter('the_title','wp_specialchars'); +while (have_posts()) : the_post(); $i_post++; +if ( 16 == $i_post ) + echo "\t</tbody>\n\t<tbody id='the-extra-list' class='list:post' style='display: none'>\n"; // Hack! +$class = ( $i_post > 15 || 'alternate' == $class) ? '' : 'alternate'; +global $current_user; +$post_owner = ( $current_user->ID == $post->post_author ? 'self' : 'other' ); +?> + <tr id='post-<?php echo $id; ?>' class='<?php echo trim( $class . ' author-' . $post_owner . ' status-' . $post->post_status ); ?>' valign="top"> + +<?php + +foreach($posts_columns as $column_name=>$column_display_name) { + + switch($column_name) { + + case 'cb': + ?> + <th scope="row" style="text-align: center"><input type="checkbox" name="delete[]" value="<?php the_ID(); ?>" /></th> + <?php + break; + + case 'icon': + ?> + <td class="media-icon"><?php echo wp_get_attachment_link($post->ID, array(60, 40), false, true); ?></td> + <?php + // TODO + break; + + case 'media': + ?> + <td><strong><a href="media.php?action=edit&attachment_id=<?php the_ID(); ?>"><?php the_title(); ?></a></strong><br /> + <?php echo strtoupper(preg_replace('/^.*?\.(\w+)$/', '$1', get_attached_file($post->ID))); ?> + <?php do_action('manage_media_media_column', $post->ID); ?> + </td> + <?php + break; + + case 'desc': + ?> + <td><?php echo has_excerpt() ? $post->post_excerpt : ''; ?></td> + <?php + break; + + case 'date': + if ( '0000-00-00 00:00:00' == $post->post_date && 'date' == $column_name ) { + $t_time = $h_time = __('Unpublished'); + } else { + $t_time = get_the_time(__('Y/m/d g:i:s A')); + $m_time = $post->post_date; + $time = get_post_time( 'G', true ); + if ( ( abs($t_diff = time() - $time) ) < 86400 ) { + if ( $t_diff < 0 ) + $h_time = sprintf( __('%s from now'), human_time_diff( $time ) ); + else + $h_time = sprintf( __('%s ago'), human_time_diff( $time ) ); + } else { + $h_time = mysql2date(__('Y/m/d'), $m_time); + } + } + ?> + <td><?php echo $h_time ?></td> + <?php + break; + + case 'parent': + if ( $post_parent = get_post($post->post_parent) ) { + $title = get_the_title($post->post_parent); + if ( empty($title) ) + $title = __('(no title)'); + } else { + $title = ''; + } + ?> + <td><strong><a href="post.php?action=edit&post=<?php echo $post->post_parent; ?>"><?php echo $title ?></a></strong></td> + <?php + break; + + case 'comments': + ?> + <td style="text-align: center"> + <?php + $left = get_pending_comments_num( $post->ID ); + $pending_phrase = sprintf( __('%s pending'), number_format( $left ) ); + if ( $left ) + echo '<strong>'; + comments_number("<a href='upload.php?attachment_id=$id' title='$pending_phrase' class='post-com-count'><span class='comment-count'>" . __('0') . '</span></a>', "<a href='upload.php?attachment_id=$id' title='$pending_phrase' class='post-com-count'><span class='comment-count'>" . __('1') . '</span></a>', "<a href='upload.php?attachment_id=$id' title='$pending_phrase' class='post-com-count'><span class='comment-count'>" . __('%') . '</span></a>'); + if ( $left ) + echo '</strong>'; + ?> + </td> + <?php + break; + + case 'location': + ?> + <td><a href="<?php the_permalink(); ?>"><?php _e('Permalink'); ?></a></td> + <?php + break; + + default: + ?> + <td><?php do_action('manage_media_custom_column', $column_name, $id); ?></td> + <?php + break; + } +} +?> + </tr> +<?php +endwhile; +} else { +?> + <tr style='background-color: <?php echo $bgcolor; ?>'> + <td colspan="8"><?php _e('No posts found.') ?></td> + </tr> +<?php +} // end if ( have_posts() ) +?> + </tbody> +</table> diff --git a/wp-admin/edit-tag-form.php b/wp-admin/edit-tag-form.php new file mode 100644 index 0000000..c3a6665 --- /dev/null +++ b/wp-admin/edit-tag-form.php @@ -0,0 +1,41 @@ +<?php +if ( ! empty($tag_ID) ) { + $heading = __('Edit Tag'); + $submit_text = __('Edit Tag'); + $form = '<form name="edittag" id="edittag" method="post" action="edit-tags.php">'; + $action = 'editedtag'; + $nonce_action = 'update-tag_' . $tag_ID; + do_action('edit_tag_form_pre', $tag); +} else { + $heading = __('Add Tag'); + $submit_text = __('Add Tag'); + $form = '<form name="addtag" id="addtag" method="post" action="edit-tags.php" class="add:the-list:">'; + $action = 'addtag'; + $nonce_action = 'add-tag'; + do_action('add_tag_form_pre', $tag); +} +?> + +<div class="wrap"> +<h2><?php echo $heading ?></h2> +<div id="ajax-response"></div> +<?php echo $form ?> +<input type="hidden" name="action" value="<?php echo $action ?>" /> +<input type="hidden" name="tag_ID" value="<?php echo $tag->term_id ?>" /> +<?php wp_nonce_field($nonce_action); ?> + <table class="form-table"> + <tr class="form-field form-required"> + <th scope="row" valign="top"><label for="name"><?php _e('Tag name') ?></label></th> + <td><input name="name" id="name" type="text" value="<?php echo attribute_escape($tag->name); ?>" size="40" /> + <p><?php _e('The name is how the tag appears on your site.'); ?></p></td> + </tr> + <tr class="form-field"> + <th scope="row" valign="top"><label for="slug"><?php _e('Tag slug') ?></label></th> + <td><input name="slug" id="slug" type="text" value="<?php echo attribute_escape($tag->slug); ?>" size="40" /> + <p><?php _e('The “slug” is the URL-friendly version of the name. It is usually all lowercase and contains only letters, numbers, and hyphens.'); ?></p></td> + </tr> + </table> +<p class="submit"><input type="submit" class="button" name="submit" value="<?php echo $submit_text ?>" /></p> +<?php do_action('edit_tag_form', $tag); ?> +</form> +</div> diff --git a/wp-admin/edit-tags.php b/wp-admin/edit-tags.php new file mode 100644 index 0000000..fe6b89f --- /dev/null +++ b/wp-admin/edit-tags.php @@ -0,0 +1,202 @@ +<?php +require_once('admin.php'); + +$title = __('Tags'); +$parent_file = 'edit.php'; + +wp_reset_vars(array('action', 'tag')); + +if ( isset($_GET['deleteit']) && isset($_GET['delete_tags']) ) + $action = 'bulk-delete'; + +switch($action) { + +case 'addtag': + + check_admin_referer('add-tag'); + + if ( !current_user_can('manage_categories') ) + wp_die(__('Cheatin’ uh?')); + + $ret = wp_insert_term($_POST['name'], 'post_tag', $_POST); + if ( $ret && !is_wp_error( $ret ) ) { + wp_redirect('edit-tags.php?message=1#addtag'); + } else { + wp_redirect('edit-tags.php?message=4#addtag'); + } + exit; +break; + +case 'delete': + $tag_ID = (int) $_GET['tag_ID']; + check_admin_referer('delete-tag_' . $tag_ID); + + if ( !current_user_can('manage_categories') ) + wp_die(__('Cheatin’ uh?')); + + wp_delete_term( $tag_ID, 'post_tag'); + + wp_redirect('edit-tags.php?message=2'); + exit; + +break; + +case 'bulk-delete': + check_admin_referer('bulk-tags'); + + if ( !current_user_can('manage_categories') ) + wp_die(__('Cheatin’ uh?')); + + $tags = $_GET['delete_tags']; + foreach( (array) $tags as $tag_ID ) { + wp_delete_term( $tag_ID, 'post_tag'); + } + + wp_redirect('edit-tags.php?message=6'); + exit; + +break; + +case 'edit': + + require_once ('admin-header.php'); + $tag_ID = (int) $_GET['tag_ID']; + + $tag = get_term($tag_ID, 'post_tag', OBJECT, 'edit'); + include('edit-tag-form.php'); + +break; + +case 'editedtag': + $tag_ID = (int) $_POST['tag_ID']; + check_admin_referer('update-tag_' . $tag_ID); + + if ( !current_user_can('manage_categories') ) + wp_die(__('Cheatin’ uh?')); + + $ret = wp_update_term($tag_ID, 'post_tag', $_POST); + if( $ret && !is_wp_error( $ret ) ) { + wp_redirect('edit-tags.php?message=3'); + } else { + wp_redirect('edit-tags.php?message=5'); + } + exit; +break; + +default: + +if ( !empty($_GET['_wp_http_referer']) ) { + wp_redirect(remove_query_arg(array('_wp_http_referer', '_wpnonce'), stripslashes($_SERVER['REQUEST_URI']))); + exit; +} + +wp_enqueue_script( 'admin-tags' ); +wp_enqueue_script('admin-forms'); + +require_once ('admin-header.php'); + +$messages[1] = __('Tag added.'); +$messages[2] = __('Tag deleted.'); +$messages[3] = __('Tag updated.'); +$messages[4] = __('Tag not added.'); +$messages[5] = __('Tag not updated.'); +$messages[6] = __('Tags deleted.'); +?> + +<?php if (isset($_GET['message'])) : ?> +<div id="message" class="updated fade"><p><?php echo $messages[$_GET['message']]; ?></p></div> +<?php $_SERVER['REQUEST_URI'] = remove_query_arg(array('message'), $_SERVER['REQUEST_URI']); +endif; ?> + +<div class="wrap"> + +<form id="posts-filter" action="" method="get"> +<?php if ( current_user_can('manage_categories') ) : ?> + <h2><?php printf(__('Manage Tags (<a href="%s">add new</a>)'), '#addtag') ?> </h2> +<?php else : ?> + <h2><?php _e('Manage Tags') ?> </h2> +<?php endif; ?> + +<p id="post-search"> + <input type="text" id="post-search-input" name="s" value="<?php echo attribute_escape(stripslashes($_GET['s'])); ?>" /> + <input type="submit" value="<?php _e( 'Search Tags' ); ?>" class="button" /> +</p> + +<br style="clear:both;" /> + +<div class="tablenav"> + +<?php +$pagenum = absint( $_GET['pagenum'] ); +if ( empty($pagenum) ) + $pagenum = 1; +if( !$tagsperpage || $tagsperpage < 0 ) + $tagsperpage = 20; + +$page_links = paginate_links( array( + 'base' => add_query_arg( 'pagenum', '%#%' ), + 'format' => '', + 'total' => ceil(wp_count_terms('post_tag') / $tagsperpage), + 'current' => $pagenum +)); + +if ( $page_links ) + echo "<div class='tablenav-pages'>$page_links</div>"; +?> + +<div style="float: left"> +<input type="submit" value="<?php _e('Delete'); ?>" name="deleteit" class="button-secondary delete" /> +<?php wp_nonce_field('bulk-tags'); ?> +</div> + +<br style="clear:both;" /> +</div> + +<br style="clear:both;" /> + +<table class="widefat"> + <thead> + <tr> + <th scope="col" class="check-column"><input type="checkbox" onclick="checkAll(document.getElementById('posts-filter'));" /></th> + <th scope="col"><?php _e('Name') ?></th> + <th scope="col" style="width: 90px"><?php _e('Posts') ?></th> + </tr> + </thead> + <tbody id="the-list" class="list:tag"> +<?php + +$searchterms = trim( $_GET['s'] ); + +$count = tag_rows( $pagenum, $tagsperpage, $searchterms ); +?> + </tbody> +</table> +</form> + +<br style="clear:both;" /> + +<div class="tablenav"> + +<?php +if ( $page_links ) + echo "<div class='tablenav-pages'>$page_links</div>"; +?> +<br style="clear:both;" /> +</div> + +</div> + +<?php if ( current_user_can('manage_categories') ) : ?> + +<br /> +<?php include('edit-tag-form.php'); ?> + +<?php endif; ?> + +<?php +break; +} + +include('admin-footer.php'); + +?> diff --git a/wp-admin/images/align-center.png b/wp-admin/images/align-center.png Binary files differnew file mode 100644 index 0000000..a412226 --- /dev/null +++ b/wp-admin/images/align-center.png diff --git a/wp-admin/images/align-left.png b/wp-admin/images/align-left.png Binary files differnew file mode 100644 index 0000000..2e433fc --- /dev/null +++ b/wp-admin/images/align-left.png diff --git a/wp-admin/images/align-none.png b/wp-admin/images/align-none.png Binary files differnew file mode 100644 index 0000000..5fb9af2 --- /dev/null +++ b/wp-admin/images/align-none.png diff --git a/wp-admin/images/align-right.png b/wp-admin/images/align-right.png Binary files differnew file mode 100644 index 0000000..9b92578 --- /dev/null +++ b/wp-admin/images/align-right.png diff --git a/wp-admin/images/box-bg-left.gif b/wp-admin/images/box-bg-left.gif Binary files differdeleted file mode 100644 index c3c7e35..0000000 --- a/wp-admin/images/box-bg-left.gif +++ /dev/null diff --git a/wp-admin/images/box-bg-right.gif b/wp-admin/images/box-bg-right.gif Binary files differdeleted file mode 100644 index 12a0d1a..0000000 --- a/wp-admin/images/box-bg-right.gif +++ /dev/null diff --git a/wp-admin/images/box-bg.gif b/wp-admin/images/box-bg.gif Binary files differdeleted file mode 100644 index 2eb7f58..0000000 --- a/wp-admin/images/box-bg.gif +++ /dev/null diff --git a/wp-admin/images/box-butt-left.gif b/wp-admin/images/box-butt-left.gif Binary files differdeleted file mode 100644 index 590c2ef..0000000 --- a/wp-admin/images/box-butt-left.gif +++ /dev/null diff --git a/wp-admin/images/box-butt-right.gif b/wp-admin/images/box-butt-right.gif Binary files differdeleted file mode 100644 index 487ebb3..0000000 --- a/wp-admin/images/box-butt-right.gif +++ /dev/null diff --git a/wp-admin/images/box-butt.gif b/wp-admin/images/box-butt.gif Binary files differdeleted file mode 100644 index 514a165..0000000 --- a/wp-admin/images/box-butt.gif +++ /dev/null diff --git a/wp-admin/images/box-head-left.gif b/wp-admin/images/box-head-left.gif Binary files differdeleted file mode 100644 index b03e075..0000000 --- a/wp-admin/images/box-head-left.gif +++ /dev/null diff --git a/wp-admin/images/box-head-right.gif b/wp-admin/images/box-head-right.gif Binary files differdeleted file mode 100644 index 897b03a..0000000 --- a/wp-admin/images/box-head-right.gif +++ /dev/null diff --git a/wp-admin/images/box-head.gif b/wp-admin/images/box-head.gif Binary files differdeleted file mode 100644 index 5c09a9a..0000000 --- a/wp-admin/images/box-head.gif +++ /dev/null diff --git a/wp-admin/images/bubble_bg.gif b/wp-admin/images/bubble_bg.gif Binary files differnew file mode 100644 index 0000000..c6f395a --- /dev/null +++ b/wp-admin/images/bubble_bg.gif diff --git a/wp-admin/images/comment-grey-bubble.png b/wp-admin/images/comment-grey-bubble.png Binary files differnew file mode 100644 index 0000000..6f1e765 --- /dev/null +++ b/wp-admin/images/comment-grey-bubble.png diff --git a/wp-admin/images/comment-pill.gif b/wp-admin/images/comment-pill.gif Binary files differnew file mode 100644 index 0000000..2fabf99 --- /dev/null +++ b/wp-admin/images/comment-pill.gif diff --git a/wp-admin/images/comment-stalk-classic.gif b/wp-admin/images/comment-stalk-classic.gif Binary files differnew file mode 100644 index 0000000..3cf83a5 --- /dev/null +++ b/wp-admin/images/comment-stalk-classic.gif diff --git a/wp-admin/images/comment-stalk-fresh.gif b/wp-admin/images/comment-stalk-fresh.gif Binary files differnew file mode 100644 index 0000000..9048949 --- /dev/null +++ b/wp-admin/images/comment-stalk-fresh.gif diff --git a/wp-admin/images/date-button.gif b/wp-admin/images/date-button.gif Binary files differnew file mode 100644 index 0000000..7ee32cb --- /dev/null +++ b/wp-admin/images/date-button.gif diff --git a/wp-admin/images/heading-bg.gif b/wp-admin/images/heading-bg.gif Binary files differdeleted file mode 100644 index bea18ca..0000000 --- a/wp-admin/images/heading-bg.gif +++ /dev/null diff --git a/wp-admin/images/login-bkg-bottom.gif b/wp-admin/images/login-bkg-bottom.gif Binary files differdeleted file mode 100644 index a78656e..0000000 --- a/wp-admin/images/login-bkg-bottom.gif +++ /dev/null diff --git a/wp-admin/images/login-bkg-tile.gif b/wp-admin/images/login-bkg-tile.gif Binary files differdeleted file mode 100644 index 1015a9e..0000000 --- a/wp-admin/images/login-bkg-tile.gif +++ /dev/null diff --git a/wp-admin/images/logo-login.gif b/wp-admin/images/logo-login.gif Binary files differnew file mode 100644 index 0000000..276faf1 --- /dev/null +++ b/wp-admin/images/logo-login.gif diff --git a/wp-admin/images/media-button-gallery.gif b/wp-admin/images/media-button-gallery.gif Binary files differnew file mode 100644 index 0000000..1191778 --- /dev/null +++ b/wp-admin/images/media-button-gallery.gif diff --git a/wp-admin/images/media-button-image.gif b/wp-admin/images/media-button-image.gif Binary files differnew file mode 100644 index 0000000..11278c8 --- /dev/null +++ b/wp-admin/images/media-button-image.gif diff --git a/wp-admin/images/media-button-music.gif b/wp-admin/images/media-button-music.gif Binary files differnew file mode 100644 index 0000000..f85cd43 --- /dev/null +++ b/wp-admin/images/media-button-music.gif diff --git a/wp-admin/images/media-button-other.gif b/wp-admin/images/media-button-other.gif Binary files differnew file mode 100644 index 0000000..f3f2f8a --- /dev/null +++ b/wp-admin/images/media-button-other.gif diff --git a/wp-admin/images/media-button-video.gif b/wp-admin/images/media-button-video.gif Binary files differnew file mode 100644 index 0000000..ceb2734 --- /dev/null +++ b/wp-admin/images/media-button-video.gif diff --git a/wp-admin/images/media-buttons.gif b/wp-admin/images/media-buttons.gif Binary files differnew file mode 100644 index 0000000..2266040 --- /dev/null +++ b/wp-admin/images/media-buttons.gif diff --git a/wp-admin/images/notice.gif b/wp-admin/images/notice.gif Binary files differdeleted file mode 100644 index ba6eab0..0000000 --- a/wp-admin/images/notice.gif +++ /dev/null diff --git a/wp-admin/images/tail.gif b/wp-admin/images/tail.gif Binary files differnew file mode 100644 index 0000000..3f8e7d5 --- /dev/null +++ b/wp-admin/images/tail.gif diff --git a/wp-admin/images/toggle-arrow.gif b/wp-admin/images/toggle-arrow.gif Binary files differnew file mode 100644 index 0000000..86cb448 --- /dev/null +++ b/wp-admin/images/toggle-arrow.gif diff --git a/wp-admin/images/toggle.gif b/wp-admin/images/toggle.gif Binary files differdeleted file mode 100644 index 72e8b44..0000000 --- a/wp-admin/images/toggle.gif +++ /dev/null diff --git a/wp-admin/images/xit.gif b/wp-admin/images/xit.gif Binary files differnew file mode 100644 index 0000000..6f1cc4f --- /dev/null +++ b/wp-admin/images/xit.gif diff --git a/wp-admin/includes/class-ftp-pure.php b/wp-admin/includes/class-ftp-pure.php new file mode 100644 index 0000000..5ef92bf --- /dev/null +++ b/wp-admin/includes/class-ftp-pure.php @@ -0,0 +1,175 @@ +<?php +/** + * PemFTP - A Ftp implementation in pure PHP + * + * @package PemFTP + * @since 2.5 + * + * @version 1.0 + * @copyright Alexey Dotsenko + * @author Alexey Dotsenko + * @link http://www.phpclasses.org/browse/package/1743.html Site + * @license LGPL License http://www.opensource.org/licenses/lgpl-license.html + */ +class ftp extends ftp_base { + + function ftp($verb=FALSE, $le=FALSE) { + $this->__construct($verb, $le); + } + + function __construct($verb=FALSE, $le=FALSE) { + parent::__construct(false, $verb, $le); + } + +// <!-- --------------------------------------------------------------------------------------- --> +// <!-- Private functions --> +// <!-- --------------------------------------------------------------------------------------- --> + + function _settimeout($sock) { + if(!@stream_set_timeout($sock, $this->_timeout)) { + $this->PushError('_settimeout','socket set send timeout'); + $this->_quit(); + return FALSE; + } + return TRUE; + } + + function _connect($host, $port) { + $this->SendMSG("Creating socket"); + $sock = @fsockopen($host, $port, $errno, $errstr, $this->_timeout); + if (!$sock) { + $this->PushError('_connect','socket connect failed', $errstr." (".$errno.")"); + return FALSE; + } + $this->_connected=true; + return $sock; + } + + function _readmsg($fnction="_readmsg"){ + if(!$this->_connected) { + $this->PushError($fnction, 'Connect first'); + return FALSE; + } + $result=true; + $this->_message=""; + $this->_code=0; + $go=true; + do { + $tmp=@fgets($this->_ftp_control_sock, 512); + if($tmp===false) { + $go=$result=false; + $this->PushError($fnction,'Read failed'); + } else { + $this->_message.=$tmp; + if(preg_match("/^([0-9]{3})(-(.*[".CRLF."]{1,2})+\\1)? [^".CRLF."]+[".CRLF."]{1,2}$/", $this->_message, $regs)) $go=false; + } + } while($go); + if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF; + $this->_code=(int)$regs[1]; + return $result; + } + + function _exec($cmd, $fnction="_exec") { + if(!$this->_ready) { + $this->PushError($fnction,'Connect first'); + return FALSE; + } + if($this->LocalEcho) echo "PUT > ",$cmd,CRLF; + $status=@fputs($this->_ftp_control_sock, $cmd.CRLF); + if($status===false) { + $this->PushError($fnction,'socket write failed'); + return FALSE; + } + $this->_lastaction=time(); + if(!$this->_readmsg($fnction)) return FALSE; + return TRUE; + } + + function _data_prepare($mode=FTP_ASCII) { + if(!$this->_settype($mode)) return FALSE; + if($this->_passive) { + if(!$this->_exec("PASV", "pasv")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $ip_port = explode(",", ereg_replace("^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*".CRLF."$", "\\1", $this->_message)); + $this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3]; + $this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]); + $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport); + $this->_ftp_data_sock=@fsockopen($this->_datahost, $this->_dataport, $errno, $errstr, $this->_timeout); + if(!$this->_ftp_data_sock) { + $this->PushError("_data_prepare","fsockopen fails", $errstr." (".$errno.")"); + $this->_data_close(); + return FALSE; + } + else $this->_ftp_data_sock; + } else { + $this->SendMSG("Only passive connections available!"); + return FALSE; + } + return TRUE; + } + + function _data_read($mode=FTP_ASCII, $fp=NULL) { + if(is_resource($fp)) $out=0; + else $out=""; + if(!$this->_passive) { + $this->SendMSG("Only passive connections available!"); + return FALSE; + } + while (!feof($this->_ftp_data_sock)) { + $block=fread($this->_ftp_data_sock, $this->_ftp_buff_size); + if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block); + if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block)); + else $out.=$block; + } + return $out; + } + + function _data_write($mode=FTP_ASCII, $fp=NULL) { + if(is_resource($fp)) $out=0; + else $out=""; + if(!$this->_passive) { + $this->SendMSG("Only passive connections available!"); + return FALSE; + } + if(is_resource($fp)) { + while(!feof($fp)) { + $block=fread($fp, $this->_ftp_buff_size); + if(!$this->_data_write_block($mode, $block)) return false; + } + } elseif(!$this->_data_write_block($mode, $fp)) return false; + return TRUE; + } + + function _data_write_block($mode, $block) { + if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block); + do { + if(($t=@fwrite($this->_ftp_data_sock, $block))===FALSE) { + $this->PushError("_data_write","Can't write to socket"); + return FALSE; + } + $block=substr($block, $t); + } while(!empty($block)); + return true; + } + + function _data_close() { + @fclose($this->_ftp_data_sock); + $this->SendMSG("Disconnected data from remote host"); + return TRUE; + } + + function _quit($force=FALSE) { + if($this->_connected or $force) { + @fclose($this->_ftp_control_sock); + $this->_connected=false; + $this->SendMSG("Socket closed"); + } + } +} +?> diff --git a/wp-admin/includes/class-ftp-sockets.php b/wp-admin/includes/class-ftp-sockets.php new file mode 100644 index 0000000..99b4050 --- /dev/null +++ b/wp-admin/includes/class-ftp-sockets.php @@ -0,0 +1,236 @@ +<?php +/** + * PemFTP - A Ftp implementation in pure PHP + * + * @package PemFTP + * @since 2.5 + * + * @version 1.0 + * @copyright Alexey Dotsenko + * @author Alexey Dotsenko + * @link http://www.phpclasses.org/browse/package/1743.html Site + * @license LGPL License http://www.opensource.org/licenses/lgpl-license.html + */ +class ftp extends ftp_base { + + function ftp($verb=FALSE, $le=FALSE) { + $this->__construct($verb, $le); + } + + function __construct($verb=FALSE, $le=FALSE) { + parent::__construct(true, $verb, $le); + } + +// <!-- --------------------------------------------------------------------------------------- --> +// <!-- Private functions --> +// <!-- --------------------------------------------------------------------------------------- --> + + function _settimeout($sock) { + if(!@socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) { + $this->PushError('_connect','socket set receive timeout',socket_strerror(socket_last_error($sock))); + @socket_close($sock); + return FALSE; + } + if(!@socket_set_option($sock, SOL_SOCKET , SO_SNDTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) { + $this->PushError('_connect','socket set send timeout',socket_strerror(socket_last_error($sock))); + @socket_close($sock); + return FALSE; + } + return true; + } + + function _connect($host, $port) { + $this->SendMSG("Creating socket"); + if(!($sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) { + $this->PushError('_connect','socket create failed',socket_strerror(socket_last_error($sock))); + return FALSE; + } + if(!$this->_settimeout($sock)) return FALSE; + $this->SendMSG("Connecting to \"".$host.":".$port."\""); + if (!($res = @socket_connect($sock, $host, $port))) { + $this->PushError('_connect','socket connect failed',socket_strerror(socket_last_error($sock))); + @socket_close($sock); + return FALSE; + } + $this->_connected=true; + return $sock; + } + + function _readmsg($fnction="_readmsg"){ + if(!$this->_connected) { + $this->PushError($fnction,'Connect first'); + return FALSE; + } + $result=true; + $this->_message=""; + $this->_code=0; + $go=true; + do { + $tmp=@socket_read($this->_ftp_control_sock, 4096, PHP_BINARY_READ); + if($tmp===false) { + $go=$result=false; + $this->PushError($fnction,'Read failed', socket_strerror(socket_last_error($this->_ftp_control_sock))); + } else { + $this->_message.=$tmp; + $go = !preg_match("/^([0-9]{3})(-.+\\1)? [^".CRLF."]+".CRLF."$/Us", $this->_message, $regs); + } + } while($go); + if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF; + $this->_code=(int)$regs[1]; + return $result; + } + + function _exec($cmd, $fnction="_exec") { + if(!$this->_ready) { + $this->PushError($fnction,'Connect first'); + return FALSE; + } + if($this->LocalEcho) echo "PUT > ",$cmd,CRLF; + $status=@socket_write($this->_ftp_control_sock, $cmd.CRLF); + if($status===false) { + $this->PushError($fnction,'socket write failed', socket_strerror(socket_last_error($this->stream))); + return FALSE; + } + $this->_lastaction=time(); + if(!$this->_readmsg($fnction)) return FALSE; + return TRUE; + } + + function _data_prepare($mode=FTP_ASCII) { + if(!$this->_settype($mode)) return FALSE; + $this->SendMSG("Creating data socket"); + $this->_ftp_data_sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + if ($this->_ftp_data_sock < 0) { + $this->PushError('_data_prepare','socket create failed',socket_strerror(socket_last_error($this->_ftp_data_sock))); + return FALSE; + } + if(!$this->_settimeout($this->_ftp_data_sock)) { + $this->_data_close(); + return FALSE; + } + if($this->_passive) { + if(!$this->_exec("PASV", "pasv")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $ip_port = explode(",", ereg_replace("^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*".CRLF."$", "\\1", $this->_message)); + $this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3]; + $this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]); + $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport); + if(!@socket_connect($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) { + $this->PushError("_data_prepare","socket_connect", socket_strerror(socket_last_error($this->_ftp_data_sock))); + $this->_data_close(); + return FALSE; + } + else $this->_ftp_temp_sock=$this->_ftp_data_sock; + } else { + if(!@socket_getsockname($this->_ftp_control_sock, $addr, $port)) { + $this->PushError("_data_prepare","can't get control socket information", socket_strerror(socket_last_error($this->_ftp_control_sock))); + $this->_data_close(); + return FALSE; + } + if(!@socket_bind($this->_ftp_data_sock,$addr)){ + $this->PushError("_data_prepare","can't bind data socket", socket_strerror(socket_last_error($this->_ftp_data_sock))); + $this->_data_close(); + return FALSE; + } + if(!@socket_listen($this->_ftp_data_sock)) { + $this->PushError("_data_prepare","can't listen data socket", socket_strerror(socket_last_error($this->_ftp_data_sock))); + $this->_data_close(); + return FALSE; + } + if(!@socket_getsockname($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) { + $this->PushError("_data_prepare","can't get data socket information", socket_strerror(socket_last_error($this->_ftp_data_sock))); + $this->_data_close(); + return FALSE; + } + if(!$this->_exec('PORT '.str_replace('.',',',$this->_datahost.'.'.($this->_dataport>>8).'.'.($this->_dataport&0x00FF)), "_port")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + } + return TRUE; + } + + function _data_read($mode=FTP_ASCII, $fp=NULL) { + $NewLine=$this->_eol_code[$this->OS_local]; + if(is_resource($fp)) $out=0; + else $out=""; + if(!$this->_passive) { + $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport); + $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock); + if($this->_ftp_temp_sock===FALSE) { + $this->PushError("_data_read","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock))); + $this->_data_close(); + return FALSE; + } + } + + while(($block=@socket_read($this->_ftp_temp_sock, $this->_ftp_buff_size, PHP_BINARY_READ))!==false) { + if($block==="") break; + if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block); + if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block)); + else $out.=$block; + } + return $out; + } + + function _data_write($mode=FTP_ASCII, $fp=NULL) { + $NewLine=$this->_eol_code[$this->OS_local]; + if(is_resource($fp)) $out=0; + else $out=""; + if(!$this->_passive) { + $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport); + $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock); + if($this->_ftp_temp_sock===FALSE) { + $this->PushError("_data_write","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock))); + $this->_data_close(); + return false; + } + } + if(is_resource($fp)) { + while(!feof($fp)) { + $block=fread($fp, $this->_ftp_buff_size); + if(!$this->_data_write_block($mode, $block)) return false; + } + } elseif(!$this->_data_write_block($mode, $fp)) return false; + return true; + } + + function _data_write_block($mode, $block) { + if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block); + do { + if(($t=@socket_write($this->_ftp_temp_sock, $block))===FALSE) { + $this->PushError("_data_write","socket_write", socket_strerror(socket_last_error($this->_ftp_temp_sock))); + $this->_data_close(); + return FALSE; + } + $block=substr($block, $t); + } while(!empty($block)); + return true; + } + + function _data_close() { + @socket_close($this->_ftp_temp_sock); + @socket_close($this->_ftp_data_sock); + $this->SendMSG("Disconnected data from remote host"); + return TRUE; + } + + function _quit() { + if($this->_connected) { + @socket_close($this->_ftp_control_sock); + $this->_connected=false; + $this->SendMSG("Socket closed"); + } + } +} +?> diff --git a/wp-admin/includes/class-ftp.php b/wp-admin/includes/class-ftp.php new file mode 100644 index 0000000..bc2720a --- /dev/null +++ b/wp-admin/includes/class-ftp.php @@ -0,0 +1,842 @@ +<?php +/** + * PemFTP - A Ftp implementation in pure PHP + * + * @package PemFTP + * @since 2.5 + * + * @version 1.0 + * @copyright Alexey Dotsenko + * @author Alexey Dotsenko + * @link http://www.phpclasses.org/browse/package/1743.html Site + * @license LGPL License http://www.opensource.org/licenses/lgpl-license.html + */ +if(!defined('CRLF')) define('CRLF',"\r\n"); +if(!defined("FTP_AUTOASCII")) define("FTP_AUTOASCII", -1); +if(!defined("FTP_BINARY")) define("FTP_BINARY", 1); +if(!defined("FTP_ASCII")) define("FTP_ASCII", 0); +if(!defined('FTP_FORCE')) define('FTP_FORCE', TRUE); +define('FTP_OS_Unix','u'); +define('FTP_OS_Windows','w'); +define('FTP_OS_Mac','m'); + +class ftp_base { + /* Public variables */ + var $LocalEcho; + var $Verbose; + var $OS_local; + var $OS_remote; + + /* Private variables */ + var $_lastaction; + var $_errors; + var $_type; + var $_umask; + var $_timeout; + var $_passive; + var $_host; + var $_fullhost; + var $_port; + var $_datahost; + var $_dataport; + var $_ftp_control_sock; + var $_ftp_data_sock; + var $_ftp_temp_sock; + var $_ftp_buff_size; + var $_login; + var $_password; + var $_connected; + var $_ready; + var $_code; + var $_message; + var $_can_restore; + var $_port_available; + var $_curtype; + var $_features; + + var $_error_array; + var $AuthorizedTransferMode; + var $OS_FullName; + var $_eol_code; + var $AutoAsciiExt; + + /* Constructor */ + function ftp_base($port_mode=FALSE) { + $this->__construct($port_mode); + } + + function __construct($port_mode=FALSE, $verb=FALSE, $le=FALSE) { + $this->LocalEcho=$le; + $this->Verbose=$verb; + $this->_lastaction=NULL; + $this->_error_array=array(); + $this->_eol_code=array(FTP_OS_Unix=>"\n", FTP_OS_Mac=>"\r", FTP_OS_Windows=>"\r\n"); + $this->AuthorizedTransferMode=array(FTP_AUTOASCII, FTP_ASCII, FTP_BINARY); + $this->OS_FullName=array(FTP_OS_Unix => 'UNIX', FTP_OS_Windows => 'WINDOWS', FTP_OS_Mac => 'MACOS'); + $this->AutoAsciiExt=array("ASP","BAT","C","CPP","CSS","CSV","JS","H","HTM","HTML","SHTML","INI","LOG","PHP3","PHTML","PL","PERL","SH","SQL","TXT"); + $this->_port_available=($port_mode==TRUE); + $this->SendMSG("Staring FTP client class".($this->_port_available?"":" without PORT mode support")); + $this->_connected=FALSE; + $this->_ready=FALSE; + $this->_can_restore=FALSE; + $this->_code=0; + $this->_message=""; + $this->_ftp_buff_size=4096; + $this->_curtype=NULL; + $this->SetUmask(0022); + $this->SetType(FTP_AUTOASCII); + $this->SetTimeout(30); + $this->Passive(!$this->_port_available); + $this->_login="anonymous"; + $this->_password="anon@ftp.com"; + $this->_features=array(); + $this->OS_local=FTP_OS_Unix; + $this->OS_remote=FTP_OS_Unix; + $this->features=array(); + if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $this->OS_local=FTP_OS_Windows; + elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'MAC') $this->OS_local=FTP_OS_Mac; + } + +// <!-- --------------------------------------------------------------------------------------- --> +// <!-- Public functions --> +// <!-- --------------------------------------------------------------------------------------- --> + + function parselisting($line) { + $is_windows = ($this->OS_remote == FTP_OS_Windows); + if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/",$line,$lucifer)) { + $b = array(); + if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix + $b['isdir'] = ($lucifer[7]=="<DIR>"); + if ( $b['isdir'] ) + $b['type'] = 'd'; + else + $b['type'] = 'f'; + $b['size'] = $lucifer[7]; + $b['month'] = $lucifer[1]; + $b['day'] = $lucifer[2]; + $b['year'] = $lucifer[3]; + $b['hour'] = $lucifer[4]; + $b['minute'] = $lucifer[5]; + $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]); + $b['am/pm'] = $lucifer[6]; + $b['name'] = $lucifer[8]; + } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) { + //echo $line."\n"; + $lcount=count($lucifer); + if ($lcount<8) return ''; + $b = array(); + $b['isdir'] = $lucifer[0]{0} === "d"; + $b['islink'] = $lucifer[0]{0} === "l"; + if ( $b['isdir'] ) + $b['type'] = 'd'; + elseif ( $b['islink'] ) + $b['type'] = 'l'; + else + $b['type'] = 'f'; + $b['perms'] = $lucifer[0]; + $b['number'] = $lucifer[1]; + $b['owner'] = $lucifer[2]; + $b['group'] = $lucifer[3]; + $b['size'] = $lucifer[4]; + if ($lcount==8) { + sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']); + sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']); + $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']); + $b['name'] = $lucifer[7]; + } else { + $b['month'] = $lucifer[5]; + $b['day'] = $lucifer[6]; + if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) { + $b['year'] = date("Y"); + $b['hour'] = $l2[1]; + $b['minute'] = $l2[2]; + } else { + $b['year'] = $lucifer[7]; + $b['hour'] = 0; + $b['minute'] = 0; + } + $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute'])); + $b['name'] = $lucifer[8]; + } + } + + return $b; + } + + function SendMSG($message = "", $crlf=true) { + if ($this->Verbose) { + echo $message.($crlf?CRLF:""); + flush(); + } + return TRUE; + } + + function SetType($mode=FTP_AUTOASCII) { + if(!in_array($mode, $this->AuthorizedTransferMode)) { + $this->SendMSG("Wrong type"); + return FALSE; + } + $this->_type=$mode; + $this->SendMSG("Transfer type: ".($this->_type==FTP_BINARY?"binary":($this->_type==FTP_ASCII?"ASCII":"auto ASCII") ) ); + return TRUE; + } + + function _settype($mode=FTP_ASCII) { + if($this->_ready) { + if($mode==FTP_BINARY) { + if($this->_curtype!=FTP_BINARY) { + if(!$this->_exec("TYPE I", "SetType")) return FALSE; + $this->_curtype=FTP_BINARY; + } + } elseif($this->_curtype!=FTP_ASCII) { + if(!$this->_exec("TYPE A", "SetType")) return FALSE; + $this->_curtype=FTP_ASCII; + } + } else return FALSE; + return TRUE; + } + + function Passive($pasv=NULL) { + if(is_null($pasv)) $this->_passive=!$this->_passive; + else $this->_passive=$pasv; + if(!$this->_port_available and !$this->_passive) { + $this->SendMSG("Only passive connections available!"); + $this->_passive=TRUE; + return FALSE; + } + $this->SendMSG("Passive mode ".($this->_passive?"on":"off")); + return TRUE; + } + + function SetServer($host, $port=21, $reconnect=true) { + if(!is_long($port)) { + $this->verbose=true; + $this->SendMSG("Incorrect port syntax"); + return FALSE; + } else { + $ip=@gethostbyname($host); + $dns=@gethostbyaddr($host); + if(!$ip) $ip=$host; + if(!$dns) $dns=$host; + if(ip2long($ip) === -1) { + $this->SendMSG("Wrong host name/address \"".$host."\""); + return FALSE; + } + $this->_host=$ip; + $this->_fullhost=$dns; + $this->_port=$port; + $this->_dataport=$port-1; + } + $this->SendMSG("Host \"".$this->_fullhost."(".$this->_host."):".$this->_port."\""); + if($reconnect){ + if($this->_connected) { + $this->SendMSG("Reconnecting"); + if(!$this->quit(FTP_FORCE)) return FALSE; + if(!$this->connect()) return FALSE; + } + } + return TRUE; + } + + function SetUmask($umask=0022) { + $this->_umask=$umask; + umask($this->_umask); + $this->SendMSG("UMASK 0".decoct($this->_umask)); + return TRUE; + } + + function SetTimeout($timeout=30) { + $this->_timeout=$timeout; + $this->SendMSG("Timeout ".$this->_timeout); + if($this->_connected) + if(!$this->_settimeout($this->_ftp_control_sock)) return FALSE; + return TRUE; + } + + function connect($server=NULL) { + if(!empty($server)) { + if(!$this->SetServer($server)) return false; + } + if($this->_ready) return true; + $this->SendMsg('Local OS : '.$this->OS_FullName[$this->OS_local]); + if(!($this->_ftp_control_sock = $this->_connect($this->_host, $this->_port))) { + $this->SendMSG("Error : Cannot connect to remote host \"".$this->_fullhost." :".$this->_port."\""); + return FALSE; + } + $this->SendMSG("Connected to remote host \"".$this->_fullhost.":".$this->_port."\". Waiting for greeting."); + do { + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + $this->_lastaction=time(); + } while($this->_code<200); + $this->_ready=true; + $syst=$this->systype(); + if(!$syst) $this->SendMSG("Can't detect remote OS"); + else { + if(preg_match("/win|dos|novell/i", $syst[0])) $this->OS_remote=FTP_OS_Windows; + elseif(preg_match("/os/i", $syst[0])) $this->OS_remote=FTP_OS_Mac; + elseif(preg_match("/(li|u)nix/i", $syst[0])) $this->OS_remote=FTP_OS_Unix; + else $this->OS_remote=FTP_OS_Mac; + $this->SendMSG("Remote OS: ".$this->OS_FullName[$this->OS_remote]); + } + if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled"); + else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features))); + return TRUE; + } + + function quit($force=false) { + if($this->_ready) { + if(!$this->_exec("QUIT") and !$force) return FALSE; + if(!$this->_checkCode() and !$force) return FALSE; + $this->_ready=false; + $this->SendMSG("Session finished"); + } + $this->_quit(); + return TRUE; + } + + function login($user=NULL, $pass=NULL) { + if(!is_null($user)) $this->_login=$user; + else $this->_login="anonymous"; + if(!is_null($pass)) $this->_password=$pass; + else $this->_password="anon@anon.com"; + if(!$this->_exec("USER ".$this->_login, "login")) return FALSE; + if(!$this->_checkCode()) return FALSE; + if($this->_code!=230) { + if(!$this->_exec((($this->_code==331)?"PASS ":"ACCT ").$this->_password, "login")) return FALSE; + if(!$this->_checkCode()) return FALSE; + } + $this->SendMSG("Authentication succeeded"); + if(empty($this->_features)) { + if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled"); + else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features))); + } + return TRUE; + } + + function pwd() { + if(!$this->_exec("PWD", "pwd")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return ereg_replace("^[0-9]{3} \"(.+)\" .+".CRLF, "\\1", $this->_message); + } + + function cdup() { + if(!$this->_exec("CDUP", "cdup")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return true; + } + + function chdir($pathname) { + if(!$this->_exec("CWD ".$pathname, "chdir")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function rmdir($pathname) { + if(!$this->_exec("RMD ".$pathname, "rmdir")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function mkdir($pathname) { + if(!$this->_exec("MKD ".$pathname, "mkdir")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function rename($from, $to) { + if(!$this->_exec("RNFR ".$from, "rename")) return FALSE; + if(!$this->_checkCode()) return FALSE; + if($this->_code==350) { + if(!$this->_exec("RNTO ".$to, "rename")) return FALSE; + if(!$this->_checkCode()) return FALSE; + } else return FALSE; + return TRUE; + } + + function filesize($pathname) { + if(!isset($this->_features["SIZE"])) { + $this->PushError("filesize", "not supported by server"); + return FALSE; + } + if(!$this->_exec("SIZE ".$pathname, "filesize")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message); + } + + function abort() { + if(!$this->_exec("ABOR", "abort")) return FALSE; + if(!$this->_checkCode()) { + if($this->_code!=426) return FALSE; + if(!$this->_readmsg("abort")) return FALSE; + if(!$this->_checkCode()) return FALSE; + } + return true; + } + + function mdtm($pathname) { + if(!isset($this->_features["MDTM"])) { + $this->PushError("mdtm", "not supported by server"); + return FALSE; + } + if(!$this->_exec("MDTM ".$pathname, "mdtm")) return FALSE; + if(!$this->_checkCode()) return FALSE; + $mdtm = ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message); + $date = sscanf($mdtm, "%4d%2d%2d%2d%2d%2d"); + $timestamp = mktime($date[3], $date[4], $date[5], $date[1], $date[2], $date[0]); + return $timestamp; + } + + function systype() { + if(!$this->_exec("SYST", "systype")) return FALSE; + if(!$this->_checkCode()) return FALSE; + $DATA = explode(" ", $this->_message); + return array($DATA[1], $DATA[3]); + } + + function delete($pathname) { + if(!$this->_exec("DELE ".$pathname, "delete")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function site($command, $fnction="site") { + if(!$this->_exec("SITE ".$command, $fnction)) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function chmod($pathname, $mode) { + if(!$this->site( sprintf('CHMOD %o %s', $mode, $pathname), "chmod")) return FALSE; + return TRUE; + } + + function restore($from) { + if(!isset($this->_features["REST"])) { + $this->PushError("restore", "not supported by server"); + return FALSE; + } + if($this->_curtype!=FTP_BINARY) { + $this->PushError("restore", "can't restore in ASCII mode"); + return FALSE; + } + if(!$this->_exec("REST ".$from, "resore")) return FALSE; + if(!$this->_checkCode()) return FALSE; + return TRUE; + } + + function features() { + if(!$this->_exec("FEAT", "features")) return FALSE; + if(!$this->_checkCode()) return FALSE; + $f=preg_split("/[".CRLF."]+/", preg_replace("/[0-9]{3}[ -].*[".CRLF."]+/", "", $this->_message), -1, PREG_SPLIT_NO_EMPTY); + $this->_features=array(); + foreach($f as $k=>$v) { + $v=explode(" ", trim($v)); + $this->_features[array_shift($v)]=$v;; + } + return true; + } + + function rawlist($pathname="", $arg="") { + return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "LIST", "rawlist"); + } + + function nlist($pathname="") { + return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "NLST", "nlist"); + } + + function is_exists($pathname) { + return $this->file_exists($pathname); + } + + function file_exists($pathname) { + $exists=true; + if(!$this->_exec("RNFR ".$pathname, "rename")) $exists=FALSE; + else { + if(!$this->_checkCode()) $exists=FALSE; + $this->abort(); + } + if($exists) $this->SendMSG("Remote file ".$pathname." exists"); + else $this->SendMSG("Remote file ".$pathname." does not exist"); + return $exists; + } + + function fget($fp, $remotefile,$rest=0) { + if($this->_can_restore and $rest!=0) fseek($fp, $rest); + $pi=pathinfo($remotefile); + if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; + else $mode=FTP_BINARY; + if(!$this->_data_prepare($mode)) { + return FALSE; + } + if($this->_can_restore and $rest!=0) $this->restore($rest); + if(!$this->_exec("RETR ".$remotefile, "get")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $out=$this->_data_read($mode, $fp); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + return $out; + } + + function get($remotefile, $localfile=NULL, $rest=0) { + if(is_null($localfile)) $localfile=$remotefile; + if (@file_exists($localfile)) $this->SendMSG("Warning : local file will be overwritten"); + $fp = @fopen($localfile, "w"); + if (!$fp) { + $this->PushError("get","can't open local file", "Cannot create \"".$localfile."\""); + return FALSE; + } + if($this->_can_restore and $rest!=0) fseek($fp, $rest); + $pi=pathinfo($remotefile); + if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; + else $mode=FTP_BINARY; + if(!$this->_data_prepare($mode)) { + fclose($fp); + return FALSE; + } + if($this->_can_restore and $rest!=0) $this->restore($rest); + if(!$this->_exec("RETR ".$remotefile, "get")) { + $this->_data_close(); + fclose($fp); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + fclose($fp); + return FALSE; + } + $out=$this->_data_read($mode, $fp); + fclose($fp); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + return $out; + } + + function fput($remotefile, $fp) { + if($this->_can_restore and $rest!=0) fseek($fp, $rest); + $pi=pathinfo($remotefile); + if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; + else $mode=FTP_BINARY; + if(!$this->_data_prepare($mode)) { + return FALSE; + } + if($this->_can_restore and $rest!=0) $this->restore($rest); + if(!$this->_exec("STOR ".$remotefile, "put")) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $ret=$this->_data_write($mode, $fp); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + return $ret; + } + + function put($localfile, $remotefile=NULL, $rest=0) { + if(is_null($remotefile)) $remotefile=$localfile; + if (!file_exists($localfile)) { + $this->PushError("put","can't open local file", "No such file or directory \"".$localfile."\""); + return FALSE; + } + $fp = @fopen($localfile, "r"); + + if (!$fp) { + $this->PushError("put","can't open local file", "Cannot read file \"".$localfile."\""); + return FALSE; + } + if($this->_can_restore and $rest!=0) fseek($fp, $rest); + $pi=pathinfo($localfile); + if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; + else $mode=FTP_BINARY; + if(!$this->_data_prepare($mode)) { + fclose($fp); + return FALSE; + } + if($this->_can_restore and $rest!=0) $this->restore($rest); + if(!$this->_exec("STOR ".$remotefile, "put")) { + $this->_data_close(); + fclose($fp); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + fclose($fp); + return FALSE; + } + $ret=$this->_data_write($mode, $fp); + fclose($fp); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + return $ret; + } + + function mput($local=".", $remote=NULL, $continious=false) { + $local=realpath($local); + if(!@file_exists($local)) { + $this->PushError("mput","can't open local folder", "Cannot stat folder \"".$local."\""); + return FALSE; + } + if(!is_dir($local)) return $this->put($local, $remote); + if(empty($remote)) $remote="."; + elseif(!$this->file_exists($remote) and !$this->mkdir($remote)) return FALSE; + if($handle = opendir($local)) { + $list=array(); + while (false !== ($file = readdir($handle))) { + if ($file != "." && $file != "..") $list[]=$file; + } + closedir($handle); + } else { + $this->PushError("mput","can't open local folder", "Cannot read folder \"".$local."\""); + return FALSE; + } + if(empty($list)) return TRUE; + $ret=true; + foreach($list as $el) { + if(is_dir($local."/".$el)) $t=$this->mput($local."/".$el, $remote."/".$el); + else $t=$this->put($local."/".$el, $remote."/".$el); + if(!$t) { + $ret=FALSE; + if(!$continious) break; + } + } + return $ret; + + } + + function mget($remote, $local=".", $continious=false) { + $list=$this->rawlist($remote, "-lA"); + if($list===false) { + $this->PushError("mget","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents"); + return FALSE; + } + if(empty($list)) return true; + if(!@file_exists($local)) { + if(!@mkdir($local)) { + $this->PushError("mget","can't create local folder", "Cannot create folder \"".$local."\""); + return FALSE; + } + } + foreach($list as $k=>$v) { + $list[$k]=$this->parselisting($v); + if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]); + } + $ret=true; + foreach($list as $el) { + if($el["type"]=="d") { + if(!$this->mget($remote."/".$el["name"], $local."/".$el["name"], $continious)) { + $this->PushError("mget", "can't copy folder", "Can't copy remote folder \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\""); + $ret=false; + if(!$continious) break; + } + } else { + if(!$this->get($remote."/".$el["name"], $local."/".$el["name"])) { + $this->PushError("mget", "can't copy file", "Can't copy remote file \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\""); + $ret=false; + if(!$continious) break; + } + } + @chmod($local."/".$el["name"], $el["perms"]); + $t=strtotime($el["date"]); + if($t!==-1 and $t!==false) @touch($local."/".$el["name"], $t); + } + return $ret; + } + + function mdel($remote, $continious=false) { + $list=$this->rawlist($remote, "-la"); + if($list===false) { + $this->PushError("mdel","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents"); + return false; + } + + foreach($list as $k=>$v) { + $list[$k]=$this->parselisting($v); + if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]); + } + $ret=true; + + foreach($list as $el) { + if ( empty($el) ) + continue; + + if($el["type"]=="d") { + if(!$this->mdel($remote."/".$el["name"], $continious)) { + $ret=false; + if(!$continious) break; + } + } else { + if (!$this->delete($remote."/".$el["name"])) { + $this->PushError("mdel", "can't delete file", "Can't delete remote file \"".$remote."/".$el["name"]."\""); + $ret=false; + if(!$continious) break; + } + } + } + + if(!$this->rmdir($remote)) { + $this->PushError("mdel", "can't delete folder", "Can't delete remote folder \"".$remote."/".$el["name"]."\""); + $ret=false; + } + return $ret; + } + + function mmkdir($dir, $mode = 0777) { + if(empty($dir)) return FALSE; + if($this->is_exists($dir) or $dir == "/" ) return TRUE; + if(!$this->mmkdir(dirname($dir), $mode)) return false; + $r=$this->mkdir($dir, $mode); + $this->chmod($dir,$mode); + return $r; + } + + function glob($pattern, $handle=NULL) { + $path=$output=null; + if(PHP_OS=='WIN32') $slash='\\'; + else $slash='/'; + $lastpos=strrpos($pattern,$slash); + if(!($lastpos===false)) { + $path=substr($pattern,0,-$lastpos-1); + $pattern=substr($pattern,$lastpos); + } else $path=getcwd(); + if(is_array($handle) and !empty($handle)) { + while($dir=each($handle)) { + if($this->glob_pattern_match($pattern,$dir)) + $output[]=$dir; + } + } else { + $handle=@opendir($path); + if($handle===false) return false; + while($dir=readdir($handle)) { + if($this->glob_pattern_match($pattern,$dir)) + $output[]=$dir; + } + closedir($handle); + } + if(is_array($output)) return $output; + return false; + } + + function glob_pattern_match($pattern,$string) { + $out=null; + $chunks=explode(';',$pattern); + foreach($chunks as $pattern) { + $escape=array('$','^','.','{','}','(',')','[',']','|'); + while(strpos($pattern,'**')!==false) + $pattern=str_replace('**','*',$pattern); + foreach($escape as $probe) + $pattern=str_replace($probe,"\\$probe",$pattern); + $pattern=str_replace('?*','*', + str_replace('*?','*', + str_replace('*',".*", + str_replace('?','.{1,1}',$pattern)))); + $out[]=$pattern; + } + if(count($out)==1) return($this->glob_regexp("^$out[0]$",$string)); + else { + foreach($out as $tester) + if($this->my_regexp("^$tester$",$string)) return true; + } + return false; + } + + function glob_regexp($pattern,$probe) { + $sensitive=(PHP_OS!='WIN32'); + return ($sensitive? + ereg($pattern,$probe): + eregi($pattern,$probe) + ); + } + + function dirlist($remote) { + $list=$this->rawlist($remote, "-la"); + if($list===false) { + $this->PushError("dirlist","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents"); + return false; + } + + $dirlist = array(); + foreach($list as $k=>$v) { + $entry=$this->parselisting($v); + if ( empty($entry) ) + continue; + + if($entry["name"]=="." or $entry["name"]=="..") + continue; + + $dirlist[$entry['name']] = $entry; + } + + return $dirlist; + } +// <!-- --------------------------------------------------------------------------------------- --> +// <!-- Private functions --> +// <!-- --------------------------------------------------------------------------------------- --> + function _checkCode() { + return ($this->_code<400 and $this->_code>0); + } + + function _list($arg="", $cmd="LIST", $fnction="_list") { + if(!$this->_data_prepare()) return false; + if(!$this->_exec($cmd.$arg, $fnction)) { + $this->_data_close(); + return FALSE; + } + if(!$this->_checkCode()) { + $this->_data_close(); + return FALSE; + } + $out=""; + if($this->_code<200) { + $out=$this->_data_read(); + $this->_data_close(); + if(!$this->_readmsg()) return FALSE; + if(!$this->_checkCode()) return FALSE; + if($out === FALSE ) return FALSE; + $out=preg_split("/[".CRLF."]+/", $out, -1, PREG_SPLIT_NO_EMPTY); +// $this->SendMSG(implode($this->_eol_code[$this->OS_local], $out)); + } + return $out; + } + +// <!-- --------------------------------------------------------------------------------------- --> +// <!-- Partie : gestion des erreurs --> +// <!-- --------------------------------------------------------------------------------------- --> +// Gnre une erreur pour traitement externe la classe + function PushError($fctname,$msg,$desc=false){ + $error=array(); + $error['time']=time(); + $error['fctname']=$fctname; + $error['msg']=$msg; + $error['desc']=$desc; + if($desc) $tmp=' ('.$desc.')'; else $tmp=''; + $this->SendMSG($fctname.': '.$msg.$tmp); + return(array_push($this->_error_array,$error)); + } + +// Rcupre une erreur externe + function PopError(){ + if(count($this->_error_array)) return(array_pop($this->_error_array)); + else return(false); + } +} + +$mod_sockets=TRUE; +if (!extension_loaded('sockets')) { + $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : ''; + if(!@dl($prefix . 'sockets.' . PHP_SHLIB_SUFFIX)) $mod_sockets=FALSE; +} +require_once "class-ftp-".($mod_sockets?"sockets":"pure").".php"; +?> diff --git a/wp-admin/includes/class-pclzip.php b/wp-admin/includes/class-pclzip.php new file mode 100644 index 0000000..d387f00 --- /dev/null +++ b/wp-admin/includes/class-pclzip.php @@ -0,0 +1,5748 @@ +<?php +// -------------------------------------------------------------------------------- +// PhpConcept Library - Zip Module 2.5 +// -------------------------------------------------------------------------------- +// License GNU/LGPL - Vincent Blavet - March 2006 +// http://www.phpconcept.net +// -------------------------------------------------------------------------------- +// +// Presentation : +// PclZip is a PHP library that manage ZIP archives. +// So far tests show that archives generated by PclZip are readable by +// WinZip application and other tools. +// +// Description : +// See readme.txt and http://www.phpconcept.net +// +// Warning : +// This library and the associated files are non commercial, non professional +// work. +// It should not have unexpected results. However if any damage is caused by +// this software the author can not be responsible. +// The use of this software is at the risk of the user. +// +// -------------------------------------------------------------------------------- +// $Id: pclzip.lib.php,v 1.44 2006/03/08 21:23:59 vblavet Exp $ +// -------------------------------------------------------------------------------- + + // ----- Constants + define( 'PCLZIP_READ_BLOCK_SIZE', 2048 ); + + // ----- File list separator + // In version 1.x of PclZip, the separator for file list is a space + // (which is not a very smart choice, specifically for windows paths !). + // A better separator should be a comma (,). This constant gives you the + // abilty to change that. + // However notice that changing this value, may have impact on existing + // scripts, using space separated filenames. + // Recommanded values for compatibility with older versions : + //define( 'PCLZIP_SEPARATOR', ' ' ); + // Recommanded values for smart separation of filenames. + define( 'PCLZIP_SEPARATOR', ',' ); + + // ----- Error configuration + // 0 : PclZip Class integrated error handling + // 1 : PclError external library error handling. By enabling this + // you must ensure that you have included PclError library. + // [2,...] : reserved for futur use + define( 'PCLZIP_ERROR_EXTERNAL', 0 ); + + // ----- Optional static temporary directory + // By default temporary files are generated in the script current + // path. + // If defined : + // - MUST BE terminated by a '/'. + // - MUST be a valid, already created directory + // Samples : + // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' ); + // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' ); + define( 'PCLZIP_TEMPORARY_DIR', '' ); + +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** +// -------------------------------------------------------------------------------- + + // ----- Global variables + $g_pclzip_version = "2.5"; + + // ----- Error codes + // -1 : Unable to open file in binary write mode + // -2 : Unable to open file in binary read mode + // -3 : Invalid parameters + // -4 : File does not exist + // -5 : Filename is too long (max. 255) + // -6 : Not a valid zip file + // -7 : Invalid extracted file size + // -8 : Unable to create directory + // -9 : Invalid archive extension + // -10 : Invalid archive format + // -11 : Unable to delete file (unlink) + // -12 : Unable to rename file (rename) + // -13 : Invalid header checksum + // -14 : Invalid archive size + define( 'PCLZIP_ERR_USER_ABORTED', 2 ); + define( 'PCLZIP_ERR_NO_ERROR', 0 ); + define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 ); + define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 ); + define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 ); + define( 'PCLZIP_ERR_MISSING_FILE', -4 ); + define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 ); + define( 'PCLZIP_ERR_INVALID_ZIP', -6 ); + define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 ); + define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 ); + define( 'PCLZIP_ERR_BAD_EXTENSION', -9 ); + define( 'PCLZIP_ERR_BAD_FORMAT', -10 ); + define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 ); + define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 ); + define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 ); + define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 ); + define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 ); + define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 ); + define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 ); + define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 ); + define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 ); + define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 ); + define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 ); + + // ----- Options values + define( 'PCLZIP_OPT_PATH', 77001 ); + define( 'PCLZIP_OPT_ADD_PATH', 77002 ); + define( 'PCLZIP_OPT_REMOVE_PATH', 77003 ); + define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 ); + define( 'PCLZIP_OPT_SET_CHMOD', 77005 ); + define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 ); + define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 ); + define( 'PCLZIP_OPT_BY_NAME', 77008 ); + define( 'PCLZIP_OPT_BY_INDEX', 77009 ); + define( 'PCLZIP_OPT_BY_EREG', 77010 ); + define( 'PCLZIP_OPT_BY_PREG', 77011 ); + define( 'PCLZIP_OPT_COMMENT', 77012 ); + define( 'PCLZIP_OPT_ADD_COMMENT', 77013 ); + define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 ); + define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 ); + define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 ); + define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 ); + // Having big trouble with crypt. Need to multiply 2 long int + // which is not correctly supported by PHP ... + //define( 'PCLZIP_OPT_CRYPT', 77018 ); + define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 ); + + // ----- File description attributes + define( 'PCLZIP_ATT_FILE_NAME', 79001 ); + define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 ); + define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 ); + + // ----- Call backs values + define( 'PCLZIP_CB_PRE_EXTRACT', 78001 ); + define( 'PCLZIP_CB_POST_EXTRACT', 78002 ); + define( 'PCLZIP_CB_PRE_ADD', 78003 ); + define( 'PCLZIP_CB_POST_ADD', 78004 ); + /* For futur use + define( 'PCLZIP_CB_PRE_LIST', 78005 ); + define( 'PCLZIP_CB_POST_LIST', 78006 ); + define( 'PCLZIP_CB_PRE_DELETE', 78007 ); + define( 'PCLZIP_CB_POST_DELETE', 78008 ); + */ + + // -------------------------------------------------------------------------------- + // Class : PclZip + // Description : + // PclZip is the class that represent a Zip archive. + // The public methods allow the manipulation of the archive. + // Attributes : + // Attributes must not be accessed directly. + // Methods : + // PclZip() : Object creator + // create() : Creates the Zip archive + // listContent() : List the content of the Zip archive + // extract() : Extract the content of the archive + // properties() : List the properties of the archive + // -------------------------------------------------------------------------------- + class PclZip + { + // ----- Filename of the zip file + var $zipname = ''; + + // ----- File descriptor of the zip file + var $zip_fd = 0; + + // ----- Internal error handling + var $error_code = 1; + var $error_string = ''; + + // ----- Current status of the magic_quotes_runtime + // This value store the php configuration for magic_quotes + // The class can then disable the magic_quotes and reset it after + var $magic_quotes_status; + + // -------------------------------------------------------------------------------- + // Function : PclZip() + // Description : + // Creates a PclZip object and set the name of the associated Zip archive + // filename. + // Note that no real action is taken, if the archive does not exist it is not + // created. Use create() for that. + // -------------------------------------------------------------------------------- + function PclZip($p_zipname) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::PclZip', "zipname=$p_zipname"); + + // ----- Tests the zlib + if (!function_exists('gzopen')) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 1, "zlib extension seems to be missing"); + die('Abort '.basename(__FILE__).' : Missing zlib extensions'); + } + + // ----- Set the attributes + $this->zipname = $p_zipname; + $this->zip_fd = 0; + $this->magic_quotes_status = -1; + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 1); + return; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // create($p_filelist, $p_add_dir="", $p_remove_dir="") + // create($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two different synopsis. The first one is historical. + // This method creates a Zip Archive. The Zip file is created in the + // filesystem. The files and directories indicated in $p_filelist + // are added in the archive. See the parameters description for the + // supported format of $p_filelist. + // When a directory is in the list, the directory and its content is added + // in the archive. + // In this synopsis, the function takes an optional variable list of + // options. See bellow the supported options. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function create($p_filelist) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::create', "filelist='$p_filelist', ..."); + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove from the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected"); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis"); + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Invalid number / type of arguments"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return 0; + } + } + } + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + if ($v_string != '') { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Ignore an empty filename"); + } + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + + // ----- Call the create fct + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list); + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // add($p_filelist, $p_add_dir="", $p_remove_dir="") + // add($p_filelist, $p_option, $p_option_value, ...) + // Description : + // This method supports two synopsis. The first one is historical. + // This methods add the list of files in an existing archive. + // If a file with the same name already exists, it is added at the end of the + // archive, the first one is still present. + // If the archive does not exist, it is created. + // Parameters : + // $p_filelist : An array containing file or directory names, or + // a string containing one filename or one directory name, or + // a string containing a list of filenames and/or directory + // names separated by spaces. + // $p_add_dir : A path to add before the real path of the archived file, + // in order to have it memorized in the archive. + // $p_remove_dir : A path to remove from the real path of the file to archive, + // in order to have a shorter path memorized in the archive. + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir + // is removed first, before $p_add_dir is added. + // Options : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_COMMENT : + // PCLZIP_OPT_ADD_COMMENT : + // PCLZIP_OPT_PREPEND_COMMENT : + // PCLZIP_CB_PRE_ADD : + // PCLZIP_CB_POST_ADD : + // Return Values : + // 0 on failure, + // The list of the added files, with a status of the add action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function add($p_filelist) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::add', "filelist='$p_filelist', ..."); + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Set default values + $v_options = array(); + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected"); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_ADD => 'optional', + PCLZIP_CB_POST_ADD => 'optional', + PCLZIP_OPT_NO_COMPRESSION => 'optional', + PCLZIP_OPT_COMMENT => 'optional', + PCLZIP_OPT_ADD_COMMENT => 'optional', + PCLZIP_OPT_PREPEND_COMMENT => 'optional' + //, PCLZIP_OPT_CRYPT => 'optional' + )); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis"); + + // ----- Get the first argument + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return 0; + } + } + } + + // ----- Init + $v_string_list = array(); + $v_att_list = array(); + $v_filedescr_list = array(); + $p_result_list = array(); + + // ----- Look if the $p_filelist is really an array + if (is_array($p_filelist)) { + + // ----- Look if the first element is also an array + // This will mean that this is a file description entry + if (isset($p_filelist[0]) && is_array($p_filelist[0])) { + $v_att_list = $p_filelist; + } + + // ----- The list is a list of string names + else { + $v_string_list = $p_filelist; + } + } + + // ----- Look if the $p_filelist is a string + else if (is_string($p_filelist)) { + // ----- Create a list from the string + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist); + } + + // ----- Invalid variable type for $p_filelist + else { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + + // ----- Reformat the string list + if (sizeof($v_string_list) != 0) { + foreach ($v_string_list as $v_string) { + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string; + } + } + + // ----- For each file in the list check the attributes + $v_supported_attributes + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory' + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional' + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional' + ); + foreach ($v_att_list as $v_entry) { + $v_result = $this->privFileDescrParseAtt($v_entry, + $v_filedescr_list[], + $v_options, + $v_supported_attributes); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + } + + // ----- Expand the filelist (expand directories) + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + + // ----- Call the create fct + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list); + return $p_result_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : listContent() + // Description : + // This public method, gives the list of the files and directories, with their + // properties. + // The properties of each entries in the list are (used also in other functions) : + // filename : Name of the file. For a create or add action it is the filename + // given by the user. For an extract function it is the filename + // of the extracted file. + // stored_filename : Name of the file / directory stored in the archive. + // size : Size of the stored file. + // compressed_size : Size of the file's data compressed in the archive + // (without the headers overhead) + // mtime : Last known modification date of the file (UNIX timestamp) + // comment : Comment associated with the file + // folder : true | false + // index : index of the file in the archive + // status : status of the action (depending of the action) : + // Values are : + // ok : OK ! + // filtered : the file / dir is not extracted (filtered by user) + // already_a_directory : the file can not be extracted because a + // directory with the same name already exists + // write_protected : the file can not be extracted because a file + // with the same name already exists and is + // write protected + // newer_exist : the file was not extracted because a newer file exists + // path_creation_fail : the file is not extracted because the folder + // does not exists and can not be created + // write_error : the file was not extracted because there was a + // error while writing the file + // read_error : the file was not extracted because there was a error + // while reading the file + // invalid_header : the file was not extracted because of an archive + // format error (bad file header) + // Note that each time a method can continue operating when there + // is an action error on a file, the error is only logged in the file status. + // Return Values : + // 0 on an unrecoverable failure, + // The list of the files in the archive. + // -------------------------------------------------------------------------------- + function listContent() + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::listContent', ""); + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return(0); + } + + // ----- Call the extracting fct + $p_list = array(); + if (($v_result = $this->privList($p_list)) != 1) + { + unset($p_list); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); + return(0); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list); + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // extract($p_path="./", $p_remove_path="") + // extract([$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method extract all the files / directories from the archive to the + // folder indicated in $p_path. + // If you want to ignore the 'root' part of path of the memorized files + // you can indicate this in the optional $p_remove_path parameter. + // By default, if a newer file with the same name already exists, the + // file is not extracted. + // + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append + // at the end of the path value of PCLZIP_OPT_PATH. + // Parameters : + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 or a negative value on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function extract() + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", ""); + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options"); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional' + )); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis"); + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); + return 0; + } + } + } + + // ----- Trace + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'"); + + // ----- Call the extracting fct + $p_list = array(); + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, + $v_remove_all_path, $v_options); + if ($v_result < 1) { + unset($p_list); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); + return(0); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list); + return $p_list; + } + // -------------------------------------------------------------------------------- + + + // -------------------------------------------------------------------------------- + // Function : + // extractByIndex($p_index, $p_path="./", $p_remove_path="") + // extractByIndex($p_index, [$p_option, $p_option_value, ...]) + // Description : + // This method supports two synopsis. The first one is historical. + // This method is doing a partial extract of the archive. + // The extracted files or folders are identified by their index in the + // archive (from 0 to n). + // Note that if the index identify a folder, only the folder entry is + // extracted, not all the files included in the archive. + // Parameters : + // $p_index : A single index (integer) or a string of indexes of files to + // extract. The form of the string is "0,4-6,8-12" with only numbers + // and '-' for range or ',' to separate ranges. No spaces or ';' + // are allowed. + // $p_path : Path where the files and directories are to be extracted + // $p_remove_path : First part ('root' part) of the memorized path + // (if any similar) to remove while extracting. + // Options : + // PCLZIP_OPT_PATH : + // PCLZIP_OPT_ADD_PATH : + // PCLZIP_OPT_REMOVE_PATH : + // PCLZIP_OPT_REMOVE_ALL_PATH : + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and + // not as files. + // The resulting content is in a new field 'content' in the file + // structure. + // This option must be used alone (any other options are ignored). + // PCLZIP_CB_PRE_EXTRACT : + // PCLZIP_CB_POST_EXTRACT : + // Return Values : + // 0 on failure, + // The list of the extracted files, with a status of the action. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + //function extractByIndex($p_index, options...) + function extractByIndex($p_index) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extractByIndex", "index='$p_index', ..."); + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return(0); + } + + // ----- Set default values + $v_options = array(); +// $v_path = "./"; + $v_path = ''; + $v_remove_path = ""; + $v_remove_all_path = false; + + // ----- Look for variable options arguments + $v_size = func_num_args(); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); + + // ----- Default values for option + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + + // ----- Look for arguments + if ($v_size > 1) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Remove form the options list the first argument + array_shift($v_arg_list); + $v_size--; + + // ----- Look for first arg + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options"); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_PATH => 'optional', + PCLZIP_OPT_REMOVE_PATH => 'optional', + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional', + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional', + PCLZIP_OPT_ADD_PATH => 'optional', + PCLZIP_CB_PRE_EXTRACT => 'optional', + PCLZIP_CB_POST_EXTRACT => 'optional', + PCLZIP_OPT_SET_CHMOD => 'optional', + PCLZIP_OPT_REPLACE_NEWER => 'optional' + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional' + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional' + )); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + + // ----- Set the arguments + if (isset($v_options[PCLZIP_OPT_PATH])) { + $v_path = $v_options[PCLZIP_OPT_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) { + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH]; + } + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) { + // ----- Check for '/' in last path char + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) { + $v_path .= '/'; + } + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH]; + } + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) { + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING not set."); + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING set."); + } + } + + // ----- Look for 2 args + // Here we need to support the first historic synopsis of the + // method. + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis"); + + // ----- Get the first argument + $v_path = $v_arg_list[0]; + + // ----- Look for the optional second argument + if ($v_size == 2) { + $v_remove_path = $v_arg_list[1]; + } + else if ($v_size > 2) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return 0; + } + } + } + + // ----- Trace + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'"); + + // ----- Trick + // Here I want to reuse extractByRule(), so I need to parse the $p_index + // with privParseOptions() + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index); + $v_options_trick = array(); + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick, + array (PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX]; + + // ----- Call the extracting fct + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); + return(0); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list); + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : + // delete([$p_option, $p_option_value, ...]) + // Description : + // This method removes files from the archive. + // If no parameters are given, then all the archive is emptied. + // Parameters : + // None or optional arguments. + // Options : + // PCLZIP_OPT_BY_INDEX : + // PCLZIP_OPT_BY_NAME : + // PCLZIP_OPT_BY_EREG : + // PCLZIP_OPT_BY_PREG : + // Return Values : + // 0 on failure, + // The list of the files which are still present in the archive. + // (see PclZip::listContent() for list entry format) + // -------------------------------------------------------------------------------- + function delete() + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", ""); + $v_result=1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return(0); + } + + // ----- Set default values + $v_options = array(); + + // ----- Look for variable options arguments + $v_size = func_num_args(); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method"); + + // ----- Look for arguments + if ($v_size > 0) { + // ----- Get the arguments + $v_arg_list = func_get_args(); + + // ----- Parse the options + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options, + array (PCLZIP_OPT_BY_NAME => 'optional', + PCLZIP_OPT_BY_EREG => 'optional', + PCLZIP_OPT_BY_PREG => 'optional', + PCLZIP_OPT_BY_INDEX => 'optional' )); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + } + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Call the delete fct + $v_list = array(); + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) { + $this->privSwapBackMagicQuotes(); + unset($v_list); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo()); + return(0); + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list); + return $v_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : deleteByIndex() + // Description : + // ***** Deprecated ***** + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered. + // -------------------------------------------------------------------------------- + function deleteByIndex($p_index) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'"); + + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list); + return $p_list; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : properties() + // Description : + // This method gives the properties of the archive. + // The properties are : + // nb : Number of files in the archive + // comment : Comment associated with the archive file + // status : not_exist, ok + // Parameters : + // None + // Return Values : + // 0 on failure, + // An array with the archive properties. + // -------------------------------------------------------------------------------- + function properties() + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::properties", ""); + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return(0); + } + + // ----- Default properties + $v_prop = array(); + $v_prop['comment'] = ''; + $v_prop['nb'] = 0; + $v_prop['status'] = 'not_exist'; + + // ----- Look if file exists + if (@is_file($this->zipname)) + { + // ----- Open the zip file + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), 0); + return 0; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return 0; + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Set the user attributes + $v_prop['comment'] = $v_central_dir['comment']; + $v_prop['nb'] = $v_central_dir['entries']; + $v_prop['status'] = 'ok'; + } + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_prop); + return $v_prop; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : duplicate() + // Description : + // This method creates an archive by copying the content of an other one. If + // the archive already exist, it is replaced by the new one without any warning. + // Parameters : + // $p_archive : The filename of a valid archive, or + // a valid PclZip object. + // Return Values : + // 1 on success. + // 0 or a negative value on error (error code). + // -------------------------------------------------------------------------------- + function duplicate($p_archive) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::duplicate", ""); + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the $p_archive is a PclZip object + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is valid PclZip object '".$p_archive->zipname."'"); + + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive->zipname); + } + + // ----- Look if the $p_archive is a string (so a filename) + else if (is_string($p_archive)) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is a filename '$p_archive'"); + + // ----- Check that $p_archive is a valid zip file + // TBC : Should also check the archive format + if (!is_file($p_archive)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); + $v_result = PCLZIP_ERR_MISSING_FILE; + } + else { + // ----- Duplicate the archive + $v_result = $this->privDuplicate($p_archive); + } + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : merge() + // Description : + // This method merge the $p_archive_to_add archive at the end of the current + // one ($this). + // If the archive ($this) does not exist, the merge becomes a duplicate. + // If the $p_archive_to_add archive does not exist, the merge is a success. + // Parameters : + // $p_archive_to_add : It can be directly the filename of a valid zip archive, + // or a PclZip object archive. + // Return Values : + // 1 on success, + // 0 or negative values on error (see below). + // -------------------------------------------------------------------------------- + function merge($p_archive_to_add) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::merge", ""); + $v_result = 1; + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Check archive + if (!$this->privCheckFormat()) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0); + return(0); + } + + // ----- Look if the $p_archive_to_add is a PclZip object + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is valid PclZip object"); + + // ----- Merge the archive + $v_result = $this->privMerge($p_archive_to_add); + } + + // ----- Look if the $p_archive_to_add is a string (so a filename) + else if (is_string($p_archive_to_add)) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is a filename"); + + // ----- Create a temporary archive + $v_object_archive = new PclZip($p_archive_to_add); + + // ----- Merge the archive + $v_result = $this->privMerge($v_object_archive); + } + + // ----- Invalid variable + else + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); + $v_result = PCLZIP_ERR_INVALID_PARAMETER; + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : errorCode() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorCode() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorCode()); + } + else { + return($this->error_code); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorName() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorName($p_with_code=false) + { + $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR', + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL', + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL', + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER', + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE', + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG', + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP', + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE', + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL', + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION', + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT', + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL', + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL', + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM', + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE', + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE', + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE' + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION' + ); + + if (isset($v_name[$this->error_code])) { + $v_value = $v_name[$this->error_code]; + } + else { + $v_value = 'NoName'; + } + + if ($p_with_code) { + return($v_value.' ('.$this->error_code.')'); + } + else { + return($v_value); + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : errorInfo() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function errorInfo($p_full=false) + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + return(PclErrorString()); + } + else { + if ($p_full) { + return($this->errorName(true)." : ".$this->error_string); + } + else { + return($this->error_string." [code ".$this->error_code."]"); + } + } + } + // -------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------- +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** +// ***** ***** +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** +// -------------------------------------------------------------------------------- + + + + // -------------------------------------------------------------------------------- + // Function : privCheckFormat() + // Description : + // This method check that the archive exists and is a valid zip archive. + // Several level of check exists. (futur) + // Parameters : + // $p_level : Level of check. Default 0. + // 0 : Check the first bytes (magic codes) (default value)) + // 1 : 0 + Check the central directory (futur) + // 2 : 1 + Check each file header (futur) + // Return Values : + // true on success, + // false on error, the error code is set. + // -------------------------------------------------------------------------------- + function privCheckFormat($p_level=0) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFormat", ""); + $v_result = true; + + // ----- Reset the file system cache + clearstatcache(); + + // ----- Reset the error handler + $this->privErrorReset(); + + // ----- Look if the file exits + if (!is_file($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo()); + return(false); + } + + // ----- Check that the file is readeable + if (!is_readable($this->zipname)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo()); + return(false); + } + + // ----- Check the magic code + // TBC + + // ----- Check the central header + // TBC + + // ----- Check each file header + // TBC + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privParseOptions() + // Description : + // This internal methods reads the variable list of arguments ($p_options_list, + // $p_size) and generate an array with the options and values ($v_result_list). + // $v_requested_options contains the options that can be present and those that + // must be present. + // $v_requested_options is an array, with the option value as key, and 'optional', + // or 'mandatory' as value. + // Parameters : + // See above. + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privParseOptions", ""); + $v_result=1; + + // ----- Read the options + $i=0; + while ($i<$p_size) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Looking for table index $i, option = '".PclZipUtilOptionText($p_options_list[$i])."(".$p_options_list[$i].")'"); + + // ----- Check if the option is supported + if (!isset($v_requested_options[$p_options_list[$i]])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Look for next option + switch ($p_options_list[$i]) { + // ----- Look for options that request a path value + case PCLZIP_OPT_PATH : + case PCLZIP_OPT_REMOVE_PATH : + case PCLZIP_OPT_ADD_PATH : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); + $i++; + break; + + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Get the value + if ( is_string($p_options_list[$i+1]) + && ($p_options_list[$i+1] != '')) { + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); + $i++; + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." set with an empty value is ignored."); + } + break; + + // ----- Look for options that request an array of string for value + case PCLZIP_OPT_BY_NAME : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); + $i++; + break; + + // ----- Look for options that request an EREG or PREG expression + case PCLZIP_OPT_BY_EREG : + case PCLZIP_OPT_BY_PREG : + //case PCLZIP_OPT_CRYPT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); + $i++; + break; + + // ----- Look for options that takes a string + case PCLZIP_OPT_COMMENT : + case PCLZIP_OPT_ADD_COMMENT : + case PCLZIP_OPT_PREPEND_COMMENT : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, + "Missing parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Get the value + if (is_string($p_options_list[$i+1])) { + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, + "Wrong parameter value for option '" + .PclZipUtilOptionText($p_options_list[$i]) + ."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); + $i++; + break; + + // ----- Look for options that request an array of index + case PCLZIP_OPT_BY_INDEX : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Get the value + $v_work_list = array(); + if (is_string($p_options_list[$i+1])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'"); + + // ----- Remove spaces + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); + + // ----- Parse items + $v_work_list = explode(",", $p_options_list[$i+1]); + } + else if (is_integer($p_options_list[$i+1])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'"); + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1]; + } + else if (is_array($p_options_list[$i+1])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array"); + $v_work_list = $p_options_list[$i+1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Reduce the index list + // each index item in the list must be a couple with a start and + // an end value : [0,3], [5-5], [8-10], ... + // ----- Check the format of each item + $v_sort_flag=false; + $v_sort_value=0; + for ($j=0; $j<sizeof($v_work_list); $j++) { + // ----- Explode the item + $v_item_list = explode("-", $v_work_list[$j]); + $v_size_item_list = sizeof($v_item_list); + + // ----- TBC : Here we might check that each item is a + // real integer ... + + // ----- Look for single value + if ($v_size_item_list == 1) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0]; + } + elseif ($v_size_item_list == 2) { + // ----- Set the option value + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0]; + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1]; + } + else { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extracted index item = [".$v_result_list[$p_options_list[$i]][$j]['start'].",".$v_result_list[$p_options_list[$i]][$j]['end']."]"); + + // ----- Look for list sort + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ..."); + $v_sort_flag=true; + + // ----- TBC : An automatic sort should be writen ... + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start']; + } + + // ----- Sort the items + if ($v_sort_flag) { + // TBC : To Be Completed + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ..."); + } + + // ----- Next option + $i++; + break; + + // ----- Look for options that request no value + case PCLZIP_OPT_REMOVE_ALL_PATH : + case PCLZIP_OPT_EXTRACT_AS_STRING : + case PCLZIP_OPT_NO_COMPRESSION : + case PCLZIP_OPT_EXTRACT_IN_OUTPUT : + case PCLZIP_OPT_REPLACE_NEWER : + case PCLZIP_OPT_STOP_ON_ERROR : + $v_result_list[$p_options_list[$i]] = true; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); + break; + + // ----- Look for options that request an octal value + case PCLZIP_OPT_SET_CHMOD : + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Get the value + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'"); + $i++; + break; + + // ----- Look for options that request a call-back + case PCLZIP_CB_PRE_EXTRACT : + case PCLZIP_CB_POST_EXTRACT : + case PCLZIP_CB_PRE_ADD : + case PCLZIP_CB_POST_ADD : + /* for futur use + case PCLZIP_CB_PRE_DELETE : + case PCLZIP_CB_POST_DELETE : + case PCLZIP_CB_PRE_LIST : + case PCLZIP_CB_POST_LIST : + */ + // ----- Check the number of parameters + if (($i+1) >= $p_size) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Get the value + $v_function_name = $p_options_list[$i+1]; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "call-back ".PclZipUtilOptionText($p_options_list[$i])." = '".$v_function_name."'"); + + // ----- Check that the value is a valid existing function + if (!function_exists($v_function_name)) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Set the attribute + $v_result_list[$p_options_list[$i]] = $v_function_name; + $i++; + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '" + .$p_options_list[$i]."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Next options + $i++; + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")"); + // ----- Look if present + if (!isset($v_result_list[$key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + } + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrParseAtt() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrParseAtt", ""); + $v_result=1; + + // ----- For each file in the list check the attributes + foreach ($p_file_list as $v_key => $v_value) { + + // ----- Check if the option is supported + if (!isset($v_requested_options[$v_key])) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Look for attribute + switch ($v_key) { + case PCLZIP_ATT_FILE_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'"); + + if ($p_filedescr['filename'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + break; + + case PCLZIP_ATT_FILE_NEW_SHORT_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'"); + + if ($p_filedescr['new_short_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + break; + + case PCLZIP_ATT_FILE_NEW_FULL_NAME : + if (!is_string($v_value)) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'"); + + if ($p_filedescr['new_full_name'] == '') { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + break; + + default : + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, + "Unknown parameter '".$v_key."'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Look for mandatory options + if ($v_requested_options !== false) { + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { + // ----- Look for mandatory option + if ($v_requested_options[$key] == 'mandatory') { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")"); + // ----- Look if present + if (!isset($p_file_list[$key])) { + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + } + } + + // end foreach + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privFileDescrExpand() + // Description : + // Parameters : + // Return Values : + // 1 on success. + // 0 on failure. + // -------------------------------------------------------------------------------- + function privFileDescrExpand(&$p_filedescr_list, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrExpand", ""); + $v_result=1; + + // ----- Create a result list + $v_result_list = array(); + + // ----- Look each entry + for ($i=0; $i<sizeof($p_filedescr_list); $i++) { + // ----- Get filedescr + $v_descr = $p_filedescr_list[$i]; + + // ----- Reduce the filename + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr before reduction :'".$v_descr['filename']."'"); + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename']); + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr after reduction :'".$v_descr['filename']."'"); + + // ----- Get type of descr + if (!file_exists($v_descr['filename'])) { + // ----- Error log + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_descr['filename']."' does not exists"); + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exists"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + if (@is_file($v_descr['filename'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a file"); + $v_descr['type'] = 'file'; + } + else if (@is_dir($v_descr['filename'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a folder"); + $v_descr['type'] = 'folder'; + } + else if (@is_link($v_descr['filename'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : link"); + // skip + continue; + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : unknown type"); + // skip + continue; + } + + // ----- Calculate the stored filename + $this->privCalculateStoredFilename($v_descr, $p_options); + + // ----- Add the descriptor in result list + $v_result_list[sizeof($v_result_list)] = $v_descr; + + // ----- Look for folder + if ($v_descr['type'] == 'folder') { + // ----- List of items in folder + $v_dirlist_descr = array(); + $v_dirlist_nb = 0; + if ($v_folder_handler = @opendir($v_descr['filename'])) { + while (($v_item_handler = @readdir($v_folder_handler)) !== false) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for '".$v_item_handler."' in the directory"); + + // ----- Skip '.' and '..' + if (($v_item_handler == '.') || ($v_item_handler == '..')) { + continue; + } + + // ----- Compose the full filename + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler; + + // ----- Look for different stored filename + // Because the name of the folder was changed, the name of the + // files/sub-folders also change + if ($v_descr['stored_filename'] != $v_descr['filename']) { + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler; + } + + $v_dirlist_nb++; + } + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to open dir '".$v_descr['filename']."' in read mode. Skipped."); + // TBC : unable to open folder in read mode + } + + // ----- Expand each element of the list + if ($v_dirlist_nb != 0) { + // ----- Expand + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Concat the resulting list + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Merging result list (size '".sizeof($v_result_list)."') with dirlist (size '".sizeof($v_dirlist_descr)."')"); + $v_result_list = array_merge($v_result_list, $v_dirlist_descr); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "merged result list is size '".sizeof($v_result_list)."'"); + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Nothing in this folder to expand."); + } + + // ----- Free local array + unset($v_dirlist_descr); + } + } + + // ----- Get the result list + $p_filedescr_list = $v_result_list; + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCreate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCreate($p_filedescr_list, &$p_result_list, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCreate", "list"); + $v_result=1; + $v_list_detail = array(); + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the file in write mode + if (($v_result = $this->privOpenFd('wb')) != 1) + { + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Add the list of files + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); + + // ----- Close + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAdd() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAdd($p_filedescr_list, &$p_result_list, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAdd", "list"); + $v_result=1; + $v_list_detail = array(); + + // ----- Look if the archive exists or is empty + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it."); + + // ----- Do a create + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Go to beginning of File + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'"); + @rewind($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'"); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset"); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = @fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Create the Central Dir files header + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + fclose($v_zip_temp_fd); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + $this->privSwapBackMagicQuotes(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = $v_central_dir['comment']; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; + } + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + $this->privSwapBackMagicQuotes(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privOpenFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privOpenFd($p_mode) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privOpenFd", 'mode='.$p_mode); + $v_result=1; + + // ----- Look if already open + if ($this->zip_fd != 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Open the zip file + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Open file in '.$p_mode.' mode'); + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCloseFd() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privCloseFd() + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCloseFd", ""); + $v_result=1; + + if ($this->zip_fd != 0) + @fclose($this->zip_fd); + $this->zip_fd = 0; + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddList() + // Description : + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is + // different from the real path of the file. This is usefull if you want to have PclTar + // running in any directory, and memorize relative path from an other directory. + // Parameters : + // $p_list : An array containing the file or directory names to add in the tar + // $p_result_list : list of added files with their properties (specially the status field) + // $p_add_dir : Path to add in the filename path archived + // $p_remove_dir : Path to remove in the filename path archived + // Return Values : + // -------------------------------------------------------------------------------- +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) + function privAddList($p_filedescr_list, &$p_result_list, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddList", "list"); + $v_result=1; + + // ----- Add the files + $v_header_list = array(); + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) + { + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($this->zip_fd); + + // ----- Create the Central Dir files header + for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++) + { + // ----- Create the file header + if ($v_header_list[$i]['status'] == 'ok') { + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + $v_count++; + } + + // ----- Transform the header to a 'usable' info + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($this->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) + { + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFileList() + // Description : + // Parameters : + // $p_filedescr_list : An array containing the file description + // or directory names to add in the zip + // $p_result_list : list of added files with their properties (specially the status field) + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFileList", "filedescr_list"); + $v_result=1; + $v_header = array(); + + // ----- Recuperate the current number of elt in list + $v_nb = sizeof($p_result_list); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Before add, list have ".$v_nb." elements"); + + // ----- Loop on the files + for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { + // ----- Format the filename + $p_filedescr_list[$j]['filename'] + = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false); + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for file '".$p_filedescr_list[$j]['filename']."'"); + + // ----- Skip empty file names + // TBC : Can this be possible ? not checked in DescrParseAtt ? + if ($p_filedescr_list[$j]['filename'] == "") { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Skip empty filename"); + continue; + } + + // ----- Check the filename + if (!file_exists($p_filedescr_list[$j]['filename'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_filedescr_list[$j]['filename']."' does not exists"); + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exists"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Look if it is a file or a dir with no all path remove option + if ( (is_file($p_filedescr_list[$j]['filename'])) + || ( is_dir($p_filedescr_list[$j]['filename']) + && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { + + // ----- Add the file + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, + $p_options); + if ($v_result != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Store the file infos + $p_result_list[$v_nb++] = $v_header; + } + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "After add, list have ".$v_nb." elements"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privAddFile() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privAddFile($p_filedescr, &$p_header, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFile", "filename='".$p_filedescr['filename']."'"); + $v_result=1; + + // ----- Working variable + $p_filename = $p_filedescr['filename']; + + // TBC : Already done in the fileAtt check ... ? + if ($p_filename == "") { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Look for a stored different filename + if (isset($p_filedescr['stored_filename'])) { + $v_stored_filename = $p_filedescr['stored_filename']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is NOT the same "'.$v_stored_filename.'"'); + } + else { + $v_stored_filename = $p_filedescr['stored_filename']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is the same'); + } + + // ----- Set the file properties + clearstatcache(); + $p_header['version'] = 20; + $p_header['version_extracted'] = 10; + $p_header['flag'] = 0; + $p_header['compression'] = 0; + $p_header['mtime'] = filemtime($p_filename); + $p_header['crc'] = 0; + $p_header['compressed_size'] = 0; + $p_header['size'] = filesize($p_filename); + $p_header['filename_len'] = strlen($p_filename); + $p_header['extra_len'] = 0; + $p_header['comment_len'] = 0; + $p_header['disk'] = 0; + $p_header['internal'] = 0; +// $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010); + $p_header['external'] = (is_file($p_filename)?0x00000000:0x00000010); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header external extension '".sprintf("0x%X",$p_header['external'])."'"); + $p_header['offset'] = 0; + $p_header['filename'] = $p_filename; + $p_header['stored_filename'] = $v_stored_filename; + $p_header['extra'] = ''; + $p_header['comment'] = ''; + $p_header['status'] = 'ok'; + $p_header['index'] = -1; + + // ----- Look for pre-add callback + if (isset($p_options[PCLZIP_CB_PRE_ADD])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_ADD]."()') is defined for the extraction"); + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);'); + if ($v_result == 0) { + // ----- Change the file status + $p_header['status'] = "skipped"; + $v_result = 1; + } + + // ----- Update the informations + // Only some fields can be modified + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) { + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New stored filename is '".$p_header['stored_filename']."'"); + } + } + + // ----- Look for empty stored filename + if ($p_header['stored_filename'] == "") { + $p_header['status'] = "filtered"; + } + + // ----- Check the path length + if (strlen($p_header['stored_filename']) > 0xFF) { + $p_header['status'] = 'filename_too_long'; + } + + // ----- Look if no error, or file not skipped + if ($p_header['status'] == 'ok') { + + // ----- Look for a file + if (is_file($p_filename)) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a file"); + // ----- Open the source file + if (($v_file = @fopen($p_filename, "rb")) == 0) { + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be compressed"); + // ----- Read the file content + $v_content_compressed = @fread($v_file, $p_header['size']); + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content_compressed); + + // ----- Set header parameters + $p_header['compressed_size'] = $p_header['size']; + $p_header['compression'] = 0; + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will be compressed"); + // ----- Read the file content + $v_content = @fread($v_file, $p_header['size']); + + // ----- Calculate the CRC + $p_header['crc'] = @crc32($v_content); + + // ----- Compress the file + $v_content_compressed = @gzdeflate($v_content); + + // ----- Set header parameters + $p_header['compressed_size'] = strlen($v_content_compressed); + $p_header['compression'] = 8; + } + + // ----- Look for encryption + /* + if ((isset($p_options[PCLZIP_OPT_CRYPT])) + && ($p_options[PCLZIP_OPT_CRYPT] != "")) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File need to be crypted ...."); + + // Should be a random header + $v_header = 'xxxxxxxxxxxx'; + $v_content_compressed = PclZipUtilZipEncrypt($v_content_compressed, + $p_header['compressed_size'], + $v_header, + $p_header['crc'], + "test"); + + $p_header['compressed_size'] += 12; + $p_header['flag'] = 1; + + // ----- Add the header to the data + $v_content_compressed = $v_header.$v_content_compressed; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size after header : ".strlen($v_content_compressed).""); + } + */ + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { + @fclose($v_file); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Write the compressed (or not) content + @fwrite($this->zip_fd, + $v_content_compressed, $p_header['compressed_size']); + + // ----- Close the file + @fclose($v_file); + } + + // ----- Look for a directory + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a folder"); + // ----- Look for directory last '/' + if (@substr($p_header['stored_filename'], -1) != '/') { + $p_header['stored_filename'] .= '/'; + } + + // ----- Set the file properties + $p_header['size'] = 0; + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked + $p_header['external'] = 0x00000010; // Value for a folder : to be checked + + // ----- Call the header generation + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) + { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + } + } + + // ----- Look for post-add callback + if (isset($p_options[PCLZIP_CB_POST_ADD])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_ADD]."()') is defined for the extraction"); + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_header, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);'); + if ($v_result == 0) { + // ----- Ignored + $v_result = 1; + } + + // ----- Update the informations + // Nothing can be modified + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCalculateStoredFilename() + // Description : + // Based on file descriptor properties and global options, this method + // calculate the filename that will be stored in the archive. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privCalculateStoredFilename(&$p_filedescr, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCalculateStoredFilename", "filename='".$p_filedescr['filename']."'"); + $v_result=1; + + // ----- Working variables + $p_filename = $p_filedescr['filename']; + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; + } + else { + $p_add_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; + } + else { + $p_remove_dir = ''; + } + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; + } + else { + $p_remove_all_dir = 0; + } + + // ----- Look for full name change + if (isset($p_filedescr['new_full_name'])) { + $v_stored_filename = $p_filedescr['new_full_name']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing full name of '".$p_filename."' for '".$v_stored_filename."'"); + } + + // ----- Look for path and/or short name change + else { + + // ----- Look for short name change + if (isset($p_filedescr['new_short_name'])) { + $v_path_info = pathinfo($p_filename); + $v_dir = ''; + if ($v_path_info['dirname'] != '') { + $v_dir = $v_path_info['dirname'].'/'; + } + $v_stored_filename = $v_dir.$p_filedescr['new_short_name']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing short name of '".$p_filename."' for '".$v_stored_filename."'"); + } + else { + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + } + + // ----- Look for all path to remove + if ($p_remove_all_dir) { + $v_stored_filename = basename($p_filename); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove all path selected change '".$p_filename."' for '".$v_stored_filename."'"); + } + // ----- Look for partial path remove + else if ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if ( (substr($p_filename, 0, 2) == "./") + || (substr($p_remove_dir, 0, 2) == "./")) { + + if ( (substr($p_filename, 0, 2) == "./") + && (substr($p_remove_dir, 0, 2) != "./")) { + $p_remove_dir = "./".$p_remove_dir; + } + if ( (substr($p_filename, 0, 2) != "./") + && (substr($p_remove_dir, 0, 2) == "./")) { + $p_remove_dir = substr($p_remove_dir, 2); + } + } + + $v_compare = PclZipUtilPathInclusion($p_remove_dir, + $v_stored_filename); + if ($v_compare > 0) { + if ($v_compare == 2) { + $v_stored_filename = ""; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Path to remove is the current folder"); + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove path '$p_remove_dir' in file '$v_stored_filename'"); + $v_stored_filename = substr($v_stored_filename, + strlen($p_remove_dir)); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Result is '$v_stored_filename'"); + } + } + } + // ----- Look for path to add + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'"); + } + } + + // ----- Filename (reduce the path of stored name) + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); + $p_filedescr['stored_filename'] = $v_stored_filename; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Stored filename will be '".$p_filedescr['stored_filename']."', strlen ".strlen($p_filedescr['stored_filename'])); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteFileHeader(&$p_header) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"'); + $v_result=1; + + // ----- Store the offset position of the file + $p_header['offset'] = ftell($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'File offset of the header :'.$p_header['offset']); + + // ----- Transform UNIX mtime to DOS format mdate/mtime + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, + $p_header['version_extracted'], $p_header['flag'], + $p_header['compression'], $v_mtime, $v_mdate, + $p_header['crc'], $p_header['compressed_size'], + $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len']); + + // ----- Write the first 148 bytes of the header in the archive + fputs($this->zip_fd, $v_binary_data, 30); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralFileHeader(&$p_header) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"'); + $v_result=1; + + // TBC + //for(reset($p_header); $key = key($p_header); next($p_header)) { + // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]); + //} + + // ----- Transform UNIX mtime to DOS format mdate/mtime + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); + $v_date = getdate($p_header['mtime']); + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2; + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday']; + + // ----- Packed data + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, + $p_header['version'], $p_header['version_extracted'], + $p_header['flag'], $p_header['compression'], + $v_mtime, $v_mdate, $p_header['crc'], + $p_header['compressed_size'], $p_header['size'], + strlen($p_header['stored_filename']), + $p_header['extra_len'], $p_header['comment_len'], + $p_header['disk'], $p_header['internal'], + $p_header['external'], $p_header['offset']); + + // ----- Write the 42 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 46); + + // ----- Write the variable fields + if (strlen($p_header['stored_filename']) != 0) + { + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename'])); + } + if ($p_header['extra_len'] != 0) + { + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']); + } + if ($p_header['comment_len'] != 0) + { + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privWriteCentralHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralHeader", 'nb_entries='.$p_nb_entries.', size='.$p_size.', offset='.$p_offset.', comment="'.$p_comment.'"'); + $v_result=1; + + // ----- Packed data + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, + $p_nb_entries, $p_size, + $p_offset, strlen($p_comment)); + + // ----- Write the 22 bytes of the header in the zip file + fputs($this->zip_fd, $v_binary_data, 22); + + // ----- Write the variable fields + if (strlen($p_comment) != 0) + { + fputs($this->zip_fd, $p_comment, strlen($p_comment)); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privList() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privList(&$p_list) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privList", "list"); + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Open the zip file + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) + { + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Go to beginning of Central Dir + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset : ".$v_central_dir['offset']."'"); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'"); + @rewind($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'"); + if (@fseek($this->zip_fd, $v_central_dir['offset'])) + { + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'"); + + // ----- Read each entry + for ($i=0; $i<$v_central_dir['entries']; $i++) + { + // ----- Read the file header + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + $v_header['index'] = $i; + + // ----- Get the only interesting attributes + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); + unset($v_header); + } + + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Magic quotes trick + $this->privSwapBackMagicQuotes(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privConvertHeader2FileInfo() + // Description : + // This function takes the file informations from the central directory + // entries and extract the interesting parameters that will be given back. + // The resulting file infos are set in the array $p_info + // $p_info['filename'] : Filename with full path. Given by user (add), + // extracted in the filesystem (extract). + // $p_info['stored_filename'] : Stored filename in the archive. + // $p_info['size'] = Size of the file. + // $p_info['compressed_size'] = Compressed size of the file. + // $p_info['mtime'] = Last modification date of the file. + // $p_info['comment'] = Comment associated with the file. + // $p_info['folder'] = true/false : indicates if the entry is a folder or not. + // $p_info['status'] = status of the action on the file. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privConvertHeader2FileInfo($p_header, &$p_info) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privConvertHeader2FileInfo", "Filename='".$p_header['filename']."'"); + $v_result=1; + + // ----- Get the interesting attributes + $p_info['filename'] = $p_header['filename']; + $p_info['stored_filename'] = $p_header['stored_filename']; + $p_info['size'] = $p_header['size']; + $p_info['compressed_size'] = $p_header['compressed_size']; + $p_info['mtime'] = $p_header['mtime']; + $p_info['comment'] = $p_header['comment']; + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010); + $p_info['index'] = $p_header['index']; + $p_info['status'] = $p_header['status']; + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractByRule() + // Description : + // Extract a file or directory depending of rules (by index, by name, ...) + // Parameters : + // $p_file_list : An array where will be placed the properties of each + // extracted file + // $p_path : Path to add while writing the extracted files + // $p_remove_path : Path to remove (from the file memorized path) while writing the + // extracted files. If the path does not match the file path, + // the file is extracted with its memorized path. + // $p_remove_path does not apply to 'list' mode. + // $p_path and $p_remove_path are commulative. + // Return Values : + // 1 on success,0 or less on error (see error code list) + // -------------------------------------------------------------------------------- + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'"); + $v_result=1; + + // ----- Magic quotes trick + $this->privDisableMagicQuotes(); + + // ----- Check the path + if ( ($p_path == "") + || ( (substr($p_path, 0, 1) != "/") + && (substr($p_path, 0, 3) != "../") + && (substr($p_path,1,2)!=":/"))) + $p_path = "./".$p_path; + + // ----- Reduce the path last (and duplicated) '/' + if (($p_path != "./") && ($p_path != "/")) + { + // ----- Look for the path end '/' + while (substr($p_path, -1) == "/") + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'"); + $p_path = substr($p_path, 0, strlen($p_path)-1); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]"); + } + } + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) + { + $p_remove_path .= '/'; + } + $p_remove_path_size = strlen($p_remove_path); + + // ----- Open the zip file + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($v_result = $this->privOpenFd('rb')) != 1) + { + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + + // ----- Read each entry + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'"); + + // ----- Read next Central dir entry + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'"); + @rewind($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'"); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'"); + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Store the index + $v_header['index'] = $i; + + // ----- Store the file position + $v_pos_entry = ftell($this->zip_fd); + + // ----- Look for the specific extract rules + $v_extract = false; + + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'"); + + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'"); + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory"); + + // ----- Look if the directory is in the filename path + if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path"); + $v_extract = true; + } + } + // ----- Look for a filename + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one."); + $v_extract = true; + } + } + } + + // ----- Look for extract by ereg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'"); + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression"); + $v_extract = true; + } + } + + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'"); + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression"); + $v_extract = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'"); + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]"); + + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range"); + $v_extract = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop"); + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop"); + break; + } + } + } + + // ----- Look for no rule, which means extract all the archive + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)"); + $v_extract = true; + } + + // ----- Check compression method + if ( ($v_extract) + && ( ($v_header['compression'] != 8) + && ($v_header['compression'] != 0))) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported compression method (".$v_header['compression'].")"); + $v_header['status'] = 'unsupported_compression'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, + "Filename '".$v_header['stored_filename']."' is " + ."compressed by an unsupported compression " + ."method (".$v_header['compression'].") "); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + + // ----- Check encrypted files + if (($v_extract) && (($v_header['flag'] & 1) == 1)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported file encryption"); + $v_header['status'] = 'unsupported_encryption'; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); + + $this->privSwapBackMagicQuotes(); + + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, + "Unsupported encryption for " + ." filename '".$v_header['stored_filename'] + ."'"); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + + // ----- Look for real extraction + if (($v_extract) && ($v_header['status'] != 'ok')) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "No need for extract"); + $v_result = $this->privConvertHeader2FileInfo($v_header, + $p_file_list[$v_nb_extracted++]); + if ($v_result != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + $v_extract = false; + } + + // ----- Look for real extraction + if ($v_extract) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'"); + + // ----- Go to the file position + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'"); + @rewind($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'"); + if (@fseek($this->zip_fd, $v_header['offset'])) + { + // ----- Close the zip file + $this->privCloseFd(); + + $this->privSwapBackMagicQuotes(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'"); + + // ----- Look for extraction as string + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { + + // ----- Extracting the file + $v_result1 = $this->privExtractFileAsString($v_header, $v_string); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Set the file content + $p_file_list[$v_nb_extracted]['content'] = $v_string; + + // ----- Next extracted file + $v_nb_extracted++; + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for extraction in standard output + elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { + // ----- Extracting the file in standard output + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + // ----- Look for normal extraction + else { + // ----- Extracting the file + $v_result1 = $this->privExtractFile($v_header, + $p_path, $p_remove_path, + $p_remove_all_path, + $p_options); + if ($v_result1 < 1) { + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1); + return $v_result1; + } + + // ----- Get the only interesting attributes + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Look for user callback abort + if ($v_result1 == 2) { + break; + } + } + } + } + + // ----- Close the zip file + $this->privCloseFd(); + $this->privSwapBackMagicQuotes(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFile() + // Description : + // Parameters : + // Return Values : + // + // 1 : ... ? + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback + // -------------------------------------------------------------------------------- + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFile', "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'"); + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'"); + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for all path to remove + if ($p_remove_all_path == true) { + // ----- Look for folder entry that not need to be extracted + if (($p_entry['external']&0x00000010)==0x00000010) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The entry is a folder : need to be filtered"); + + $p_entry['status'] = "filtered"; + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "All path is removed"); + // ----- Get the basename of the path + $p_entry['filename'] = basename($p_entry['filename']); + } + + // ----- Look for path to remove + else if ($p_remove_path != "") + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look for some path to remove"); + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The folder is the same as the removed path '".$p_entry['filename']."'"); + + // ----- Change the file status + $p_entry['status'] = "filtered"; + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + $p_remove_path_size = strlen($p_remove_path); + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '".$p_entry['filename']."'"); + + // ----- Remove the path + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Resulting file is '".$p_entry['filename']."'"); + } + } + + // ----- Add the path + if ($p_path != '') { + $p_entry['filename'] = $p_path."/".$p_entry['filename']; + } + + // ----- Check a base_dir_restriction + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Check the extract directory restriction"); + $v_inclusion + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], + $p_entry['filename']); + if ($v_inclusion == 0) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_EXTRACT_DIR_RESTRICTION is selected, file is outside restriction"); + + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, + "Filename '".$p_entry['filename']."' is " + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction"); + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'"); + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'"); + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Look for specific actions while the file exist + if (file_exists($p_entry['filename'])) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_entry['filename']."' already exists"); + + // ----- Look if file is a directory + if (is_dir($p_entry['filename'])) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is a directory"); + + // ----- Change the file status + $p_entry['status'] = "already_a_directory"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); + + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, + "Filename '".$p_entry['filename']."' is " + ."already used by an existing directory"); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + // ----- Look if file is write protected + else if (!is_writeable($p_entry['filename'])) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is write protected"); + + // ----- Change the file status + $p_entry['status'] = "write_protected"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Filename '".$p_entry['filename']."' exists " + ."and is write protected"); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + + // ----- Look if the extracted file is older + else if (filemtime($p_entry['filename']) > $p_entry['mtime']) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is newer (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")"); + // ----- Change the file status + if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_REPLACE_NEWER is selected, file will be replaced"); + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be replaced"); + $p_entry['status'] = "newer_exist"; + + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR + // For historical reason first PclZip implementation does not stop + // when this kind of error occurs. + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); + + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, + "Newer version of '".$p_entry['filename']."' exists " + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is older than the extrated one - will be replaced by the extracted one (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")"); + } + } + + // ----- Check the directory availability and create it if necessary + else { + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/')) + $v_dir_to_check = $p_entry['filename']; + else if (!strstr($p_entry['filename'], "/")) + $v_dir_to_check = ""; + else + $v_dir_to_check = dirname($p_entry['filename']); + + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'"); + + // ----- Change the file status + $p_entry['status'] = "path_creation_fail"; + + // ----- Return + ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + //return $v_result; + $v_result = 1; + } + } + } + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file + if ($p_entry['compression'] == 0) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file"); + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode"); + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read '".$p_entry['size']."' bytes"); + + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks + $v_size = $p_entry['compressed_size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read $v_read_size bytes"); + $v_buffer = @fread($this->zip_fd, $v_read_size); + /* Try to speed up the code + $v_binary_data = pack('a'.$v_read_size, $v_buffer); + @fwrite($v_dest_file, $v_binary_data, $v_read_size); + */ + @fwrite($v_dest_file, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Closing the destination file + fclose($v_dest_file); + + // ----- Change the file mtime + touch($p_entry['filename'], $p_entry['mtime']); + + + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (Compression method ".$p_entry['compression'].")"); + // ----- TBC + // Need to be finished + if (($p_entry['flag'] & 1) == 1) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File is encrypted"); + /* + // ----- Read the encryption header + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read 12 encryption header bytes"); + $v_encryption_header = @fread($this->zip_fd, 12); + + // ----- Read the encrypted & compressed file in a buffer + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".($p_entry['compressed_size']-12)."' compressed & encrypted bytes"); + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']-12); + + // ----- Decrypt the buffer + $this->privDecrypt($v_encryption_header, $v_buffer, + $p_entry['compressed_size']-12, $p_entry['crc']); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Buffer is '".$v_buffer."'"); + */ + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".$p_entry['compressed_size']."' compressed bytes"); + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + } + + // ----- Decompress the file + $v_file_content = @gzinflate($v_buffer); + unset($v_buffer); + if ($v_file_content === FALSE) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to inflate compressed file"); + + // ----- Change the file status + // TBC + $p_entry['status'] = "error"; + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Opening destination file + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode"); + + // ----- Change the file status + $p_entry['status'] = "write_error"; + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Write the uncompressed data + @fwrite($v_dest_file, $v_file_content, $p_entry['size']); + unset($v_file_content); + + // ----- Closing the destination file + @fclose($v_dest_file); + + // ----- Change the file mtime + @touch($p_entry['filename'], $p_entry['mtime']); + } + + // ----- Look for chmod option + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "chmod option activated '".$p_options[PCLZIP_OPT_SET_CHMOD]."'"); + + // ----- Change the mode of the file + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done"); + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction"); + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + + // ----- Look for abort result + if ($v_result == 2) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileInOutput() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileInOutput(&$p_entry, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileInOutput', ""); + $v_result=1; + + // ----- Read the file header + if (($v_result = $this->privReadFileHeader($v_header)) != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'"); + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + // ----- Look for pre-extract callback + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction"); + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); + if ($v_result == 0) { + // ----- Change the file status + $p_entry['status'] = "skipped"; + $v_result = 1; + } + + // ----- Look for abort result + if ($v_result == 2) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); + // ----- This status is internal and will be changed in 'skipped' + $p_entry['status'] = "aborted"; + $v_result = PCLZIP_ERR_USER_ABORTED; + } + + // ----- Update the informations + // Only some fields can be modified + $p_entry['filename'] = $v_local_header['filename']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'"); + } + + // ----- Trace + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'"); + + // ----- Look if extraction should be done + if ($p_entry['status'] == 'ok') { + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) { + // ----- Look for not compressed file + if ($p_entry['compressed_size'] == $p_entry['size']) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file"); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes"); + + // ----- Read the file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Send the file to the output + echo $v_buffer; + unset($v_buffer); + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file"); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Reading '".$p_entry['size']."' bytes"); + + // ----- Read the compressed file in a buffer (one shot) + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + $v_file_content = gzinflate($v_buffer); + unset($v_buffer); + + // ----- Send the file to the output + echo $v_file_content; + unset($v_file_content); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done"); + } + } + + // ----- Change abort status + if ($p_entry['status'] == "aborted") { + $p_entry['status'] = "skipped"; + } + + // ----- Look for post-extract callback + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction"); + + // ----- Generate a local information + $v_local_header = array(); + $this->privConvertHeader2FileInfo($p_entry, $v_local_header); + + // ----- Call the callback + // Here I do not use call_user_func() because I need to send a reference to the + // header. + eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); + + // ----- Look for abort result + if ($v_result == 2) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); + $v_result = PCLZIP_ERR_USER_ABORTED; + } + } + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privExtractFileAsString() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privExtractFileAsString(&$p_entry, &$p_string) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileAsString', "p_entry['filename']='".$p_entry['filename']."'"); + $v_result=1; + + // ----- Read the file header + $v_header = array(); + if (($v_result = $this->privReadFileHeader($v_header)) != 1) + { + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'"); + + // ----- Check that the file header is coherent with $p_entry info + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { + // TBC + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'"); + + // ----- Do the extraction (if not a folder) + if (!(($p_entry['external']&0x00000010)==0x00000010)) + { + // ----- Look for not compressed file +// if ($p_entry['compressed_size'] == $p_entry['size']) + if ($p_entry['compression'] == 0) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file"); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes"); + + // ----- Reading the file + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']); + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (compression method '".$p_entry['compression']."')"); + + // ----- Reading the file + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']); + + // ----- Decompress the file + if (($p_string = @gzinflate($v_data)) === FALSE) { + // TBC + } + } + + // ----- Trace + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done"); + } + else { + // TBC : error : can not extract a folder in a string + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadFileHeader(&$p_header) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadFileHeader", ""); + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'"); + $v_data = unpack('Vid', $v_binary_data); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'"); + + // ----- Check signature + if ($v_data['id'] != 0x04034b50) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid File header"); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 26); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 26) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Extract the values + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'"); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'"); + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); + + // ----- Get filename + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$v_data['filename_len']); + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : \''.$p_header['filename'].'\''); + + // ----- Get extra_fields + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra field length : ".$v_data['extra_len']); + if ($v_data['extra_len'] != 0) { + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']); + } + else { + $p_header['extra'] = ''; + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra field : \''.bin2hex($p_header['extra']).'\''); + + // ----- Extract properties + $p_header['version_extracted'] = $v_data['version']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : ('.$p_header['version_extracted'].') \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\''); + $p_header['compression'] = $v_data['compression']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compression method : \''.$p_header['compression'].'\''); + $p_header['size'] = $v_data['size']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_header['size'].'\''); + $p_header['compressed_size'] = $v_data['compressed_size']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_header['compressed_size'].'\''); + $p_header['crc'] = $v_data['crc']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\''); + $p_header['flag'] = $v_data['flag']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : \''.$p_header['flag'].'\''); + $p_header['filename_len'] = $v_data['filename_len']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename_len : \''.$p_header['filename_len'].'\''); + + // ----- Recuperate date in UNIX format + $p_header['mdate'] = $v_data['mdate']; + $p_header['mtime'] = $v_data['mtime']; + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); + } + else + { + $p_header['mtime'] = time(); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); + } + + // TBC + //for(reset($v_data); $key = key($v_data); next($v_data)) { + // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Attribut[$key] = ".$v_data[$key]); + //} + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set the status field + $p_header['status'] = "ok"; + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadCentralFileHeader() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadCentralFileHeader(&$p_header) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadCentralFileHeader", ""); + $v_result=1; + + // ----- Read the 4 bytes signature + $v_binary_data = @fread($this->zip_fd, 4); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'"); + $v_data = unpack('Vid', $v_binary_data); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'"); + + // ----- Check signature + if ($v_data['id'] != 0x02014b50) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid Central Dir File signature"); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Read the first 42 bytes of the header + $v_binary_data = fread($this->zip_fd, 42); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 42) + { + $p_header['filename'] = ""; + $p_header['status'] = "invalid_header"; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Extract the values + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'"); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'"); + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); + + // ----- Get filename + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']); + if ($p_header['filename_len'] != 0) + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']); + else + $p_header['filename'] = ''; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : \''.$p_header['filename'].'\''); + + // ----- Get extra + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']); + if ($p_header['extra_len'] != 0) + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']); + else + $p_header['extra'] = ''; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : \''.$p_header['extra'].'\''); + + // ----- Get comment + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']); + if ($p_header['comment_len'] != 0) + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']); + else + $p_header['comment'] = ''; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : \''.$p_header['comment'].'\''); + + // ----- Extract properties + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : \''.($p_header['version']/10).'.'.($p_header['version']%10).'\''); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\''); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : \''.$p_header['size'].'\''); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : \''.$p_header['compressed_size'].'\''); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\''); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : \''.$p_header['flag'].'\''); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : \''.$p_header['offset'].'\''); + + // ----- Recuperate date in UNIX format + if ($p_header['mdate'] && $p_header['mtime']) + { + // ----- Extract time + $v_hour = ($p_header['mtime'] & 0xF800) >> 11; + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; + $v_seconde = ($p_header['mtime'] & 0x001F)*2; + + // ----- Extract date + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; + $v_month = ($p_header['mdate'] & 0x01E0) >> 5; + $v_day = $p_header['mdate'] & 0x001F; + + // ----- Get UNIX date format + $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); + } + else + { + $p_header['mtime'] = time(); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\''); + } + + // ----- Set the stored filename + $p_header['stored_filename'] = $p_header['filename']; + + // ----- Set default status to ok + $p_header['status'] = 'ok'; + + // ----- Look if it is a directory + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'"); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "External (Hex) : '".sprintf("Ox%04X", $p_header['external'])."' (".(($p_header['external']&0x00000010)==0x00000010?'is a folder':'is a file').')'); + if (substr($p_header['filename'], -1) == '/') { + //$p_header['external'] = 0x41FF0010; + $p_header['external'] = 0x00000010; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : \''.sprintf("Ox%04X", $p_header['external']).'\''); + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : \''.$p_header['filename'].'\''); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privCheckFileHeaders() + // Description : + // Parameters : + // Return Values : + // 1 on success, + // 0 on error; + // -------------------------------------------------------------------------------- + function privCheckFileHeaders(&$p_local_header, &$p_central_header) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFileHeaders", ""); + $v_result=1; + + // ----- Check the static values + // TBC + if ($p_local_header['filename'] != $p_central_header['filename']) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename" : TBC To Be Completed'); + } + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "version_extracted" : TBC To Be Completed'); + } + if ($p_local_header['flag'] != $p_central_header['flag']) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "flag" : TBC To Be Completed'); + } + if ($p_local_header['compression'] != $p_central_header['compression']) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "compression" : TBC To Be Completed'); + } + if ($p_local_header['mtime'] != $p_central_header['mtime']) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "mtime" : TBC To Be Completed'); + } + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename_len" : TBC To Be Completed'); + } + + // ----- Look for flag bit 3 + if (($p_local_header['flag'] & 8) == 8) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Purpose bit flag bit 3 set !'); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'File size, compression size and crc found in central header'); + $p_local_header['size'] = $p_central_header['size']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_local_header['size'].'\''); + $p_local_header['compressed_size'] = $p_central_header['compressed_size']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_local_header['compressed_size'].'\''); + $p_local_header['crc'] = $p_central_header['crc']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_local_header['crc']).'\''); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privReadEndCentralDir() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privReadEndCentralDir(&$p_central_dir) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadEndCentralDir", ""); + $v_result=1; + + // ----- Go to the end of the zip file + $v_size = filesize($this->zipname); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size of the file :$v_size"); + @fseek($this->zip_fd, $v_size); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position at end of zip file : \''.ftell($this->zip_fd).'\''); + if (@ftell($this->zip_fd) != $v_size) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\''); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- First try : look if this is an archive with no commentaries (most of the time) + // in this case the end of central dir is at 22 bytes of the file end + $v_found = 0; + if ($v_size > 26) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Look for central dir with no comment'); + @fseek($this->zip_fd, $v_size-22); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after min central position : \''.ftell($this->zip_fd).'\''); + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Read for bytes + $v_binary_data = @fread($this->zip_fd, 4); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Binary data is : '".sprintf("%08x", $v_binary_data)."'"); + $v_data = @unpack('Vid', $v_binary_data); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'"); + + // ----- Check signature + if ($v_data['id'] == 0x06054b50) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found central dir at the default position."); + $v_found = 1; + } + + $v_pos = ftell($this->zip_fd); + } + + // ----- Go back to the maximum possible size of the Central Dir End Record + if (!$v_found) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Start extended search of end central dir'); + $v_maximum_size = 65557; // 0xFFFF + 22; + if ($v_maximum_size > $v_size) + $v_maximum_size = $v_size; + @fseek($this->zip_fd, $v_size-$v_maximum_size); + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\''); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after max central position : \''.ftell($this->zip_fd).'\''); + + // ----- Read byte per byte in order to find the signature + $v_pos = ftell($this->zip_fd); + $v_bytes = 0x00000000; + while ($v_pos < $v_size) + { + // ----- Read a byte + $v_byte = @fread($this->zip_fd, 1); + + // ----- Add the byte + $v_bytes = ($v_bytes << 8) | Ord($v_byte); + + // ----- Compare the bytes + if ($v_bytes == 0x504b0506) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Found End Central Dir signature at position : \''.ftell($this->zip_fd).'\''); + $v_pos++; + break; + } + + $v_pos++; + } + + // ----- Look if not found end of central dir + if ($v_pos == $v_size) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to find End of Central Dir Record signature"); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + + // ----- Read the first 18 bytes of the header + $v_binary_data = fread($this->zip_fd, 18); + + // ----- Look for invalid block size + if (strlen($v_binary_data) != 18) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data)); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Extract the values + ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record : '".$v_binary_data."'"); + ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record (Hex) : '".bin2hex($v_binary_data)."'"); + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data); + + // ----- Check the global size + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$v_data['comment_size']); + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The central dir is not at the end of the archive. Some trailing bytes exists after the archive."); + + // ----- Removed in release 2.2 see readme file + // The check of the file size is a little too strict. + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'. + // While decrypted, zip has training 0 bytes + if (0) { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, + 'The central dir is not at the end of the archive.' + .' Some trailing bytes exists after the archive.'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + } + + // ----- Get comment + if ($v_data['comment_size'] != 0) + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']); + else + $p_central_dir['comment'] = ''; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_central_dir['comment'].'\''); + + $p_central_dir['entries'] = $v_data['entries']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries : \''.$p_central_dir['entries'].'\''); + $p_central_dir['disk_entries'] = $v_data['disk_entries']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries for this disk : \''.$p_central_dir['disk_entries'].'\''); + $p_central_dir['offset'] = $v_data['offset']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset of Central Dir : \''.$p_central_dir['offset'].'\''); + $p_central_dir['size'] = $v_data['size']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size of Central Dir : \''.$p_central_dir['size'].'\''); + $p_central_dir['disk'] = $v_data['disk']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Disk number : \''.$p_central_dir['disk'].'\''); + $p_central_dir['disk_start'] = $v_data['disk_start']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Start disk number : \''.$p_central_dir['disk_start'].'\''); + + // TBC + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) { + // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "central_dir[$key] = ".$p_central_dir[$key]); + //} + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDeleteByRule() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDeleteByRule(&$p_result_list, &$p_options) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", ""); + $v_result=1; + $v_list_detail = array(); + + // ----- Open the zip file + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Go to beginning of File + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'"); + @rewind($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'"); + + // ----- Scan all the files + // ----- Start at beginning of Central Dir + $v_pos_entry = $v_central_dir['offset']; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'"); + @rewind($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'"); + if (@fseek($this->zip_fd, $v_pos_entry)) + { + // ----- Close the zip file + $this->privCloseFd(); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'"); + + // ----- Read each entry + $v_header_list = array(); + $j_start = 0; + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')"); + + // ----- Read the file header + $v_header_list[$v_nb_extracted] = array(); + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) + { + // ----- Close the zip file + $this->privCloseFd(); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'"); + + // ----- Store the index + $v_header_list[$v_nb_extracted]['index'] = $i; + + // ----- Look for the specific extract rules + $v_found = false; + + // ----- Look for extract by name rule + if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'"); + + // ----- Look if the filename is in the list + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'"); + + // ----- Look for a directory + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory"); + + // ----- Look if the directory is in the filename path + if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path"); + $v_found = true; + } + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */ + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory"); + $v_found = true; + } + } + // ----- Look for a filename + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one."); + $v_found = true; + } + } + } + + // ----- Look for extract by ereg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'"); + + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression"); + $v_found = true; + } + } + + // ----- Look for extract by preg rule + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'"); + + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression"); + $v_found = true; + } + } + + // ----- Look for extract by index rule + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'"); + + // ----- Look if the index is in the list + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]"); + + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range"); + $v_found = true; + } + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop"); + $j_start = $j+1; + } + + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop"); + break; + } + } + } + else { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "No argument mean remove all file"); + $v_found = true; + } + + // ----- Look for deletion + if ($v_found) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted"); + unset($v_header_list[$v_nb_extracted]); + } + else + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted"); + $v_nb_extracted++; + } + } + + // ----- Look if something need to be deleted + if ($v_nb_extracted > 0) { + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Creates a temporary zip archive + $v_temp_zip = new PclZip($v_zip_temp_name); + + // ----- Open the temporary zip file in write mode + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode"); + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) { + $this->privCloseFd(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Look which file need to be kept + for ($i=0; $i<sizeof($v_header_list); $i++) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'"); + + // ----- Calculate the position of the header + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'"); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'"); + @rewind($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'"); + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'"); + + // ----- Read the file header + $v_local_header = array(); + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Check that local file header is same as central file header + if ($this->privCheckFileHeaders($v_local_header, + $v_header_list[$i]) != 1) { + // TBC + } + unset($v_local_header); + + // ----- Write the file header + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'"); + + // ----- Read/write the data block + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) { + // ----- Close the zip file + $this->privCloseFd(); + $v_temp_zip->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_temp_zip->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset"); + + // ----- Re-Create the Central Dir files header + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory"); + for ($i=0; $i<sizeof($v_header_list); $i++) { + // ----- Create the file header + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']); + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) { + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Transform the header to a 'usable' info + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); + } + + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer"); + + // ----- Zip file comment + $v_comment = ''; + if (isset($p_options[PCLZIP_OPT_COMMENT])) { + $v_comment = $p_options[PCLZIP_OPT_COMMENT]; + } + + // ----- Calculate the size of the central header + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset; + + // ----- Create the central dir footer + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) { + // ----- Reset the file list + unset($v_header_list); + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + @unlink($v_zip_temp_name); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Close + $v_temp_zip->privCloseFd(); + $this->privCloseFd(); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Destroy the temporary archive + unset($v_temp_zip); + } + + // ----- Remove every files : reset the file + else if ($v_central_dir['entries'] != 0) { + $this->privCloseFd(); + + if (($v_result = $this->privOpenFd('wb')) != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + $this->privCloseFd(); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDirCheck() + // Description : + // Check if a directory exists, if not it creates it and all the parents directory + // which may be useful. + // Parameters : + // $p_dir : Directory path to check. + // Return Values : + // 1 : OK + // -1 : Unable to create directory + // -------------------------------------------------------------------------------- + function privDirCheck($p_dir, $p_is_dir=false) + { + $v_result = 1; + + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDirCheck", "entry='$p_dir', is_dir='".($p_is_dir?"true":"false")."'"); + + // ----- Remove the final '/' + if (($p_is_dir) && (substr($p_dir, -1)=='/')) + { + $p_dir = substr($p_dir, 0, strlen($p_dir)-1); + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Looking for entry '$p_dir'"); + + // ----- Check the directory availability + if ((is_dir($p_dir)) || ($p_dir == "")) + { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory"); + return 1; + } + + // ----- Extract parent directory + $p_parent_dir = dirname($p_dir); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'"); + + // ----- Just a check + if ($p_parent_dir != $p_dir) + { + // ----- Look for parent directory + if ($p_parent_dir != "") + { + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) + { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + } + } + + // ----- Create the directory + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'"); + if (!@mkdir($p_dir, 0777)) + { + // ----- Error log + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'"); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created"); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privMerge() + // Description : + // If $p_archive_to_add does not exist, the function exit with a success result. + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privMerge(&$p_archive_to_add) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privMerge", "archive='".$p_archive_to_add->zipname."'"); + $v_result=1; + + // ----- Look if the archive_to_add exists + if (!is_file($p_archive_to_add->zipname)) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to add does not exist. End of merge."); + + // ----- Nothing to merge, so merge is a success + $v_result = 1; + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Look if the archive exists + if (!is_file($this->zipname)) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, duplicate the archive_to_add."); + + // ----- Do a duplicate + $v_result = $this->privDuplicate($p_archive_to_add->zipname); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Open the zip file + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($v_result=$this->privOpenFd('rb')) != 1) + { + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir = array(); + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) + { + $this->privCloseFd(); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Go to beginning of File + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'"); + @rewind($this->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'"); + + // ----- Open the archive_to_add file + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open archive_to_add in binary read mode"); + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1) + { + $this->privCloseFd(); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Read the central directory informations + $v_central_dir_to_add = array(); + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Go to beginning of File + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'"); + @rewind($p_archive_to_add->zip_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'"); + + // ----- Creates a temporay file + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp'; + + // ----- Open the temporary file in write mode + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = $v_central_dir['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the files from the archive_to_add into the temporary file + $v_size = $v_central_dir_to_add['offset']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Store the offset of the central dir + $v_offset = @ftell($v_zip_temp_fd); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset"); + + // ----- Copy the block of file headers from the old archive + $v_size = $v_central_dir['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = @fread($this->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Copy the block of file headers from the archive_to_add + $v_size = $v_central_dir_to_add['size']; + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Merge the file comments + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; + + // ----- Calculate the size of the (new) central header + $v_size = @ftell($v_zip_temp_fd)-$v_offset; + + // ----- Swap the file descriptor + // Here is a trick : I swap the temporary fd with the zip fd, in order to use + // the following methods on the temporary fil and not the real archive fd + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Create the central dir footer + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1) + { + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + @fclose($v_zip_temp_fd); + $this->zip_fd = null; + + // ----- Reset the file list + unset($v_header_list); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Swap back the file descriptor + $v_swap = $this->zip_fd; + $this->zip_fd = $v_zip_temp_fd; + $v_zip_temp_fd = $v_swap; + + // ----- Close + $this->privCloseFd(); + $p_archive_to_add->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Delete the zip file + // TBC : I should test the result ... + @unlink($this->zipname); + + // ----- Rename the temporary file + // TBC : I should test the result ... + //@rename($v_zip_temp_name, $this->zipname); + PclZipUtilRename($v_zip_temp_name, $this->zipname); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDuplicate() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDuplicate($p_archive_filename) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDuplicate", "archive_filename='$p_archive_filename'"); + $v_result=1; + + // ----- Look if the $p_archive_filename exists + if (!is_file($p_archive_filename)) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to duplicate does not exist. End of duplicate."); + + // ----- Nothing to duplicate, so duplicate is a success. + $v_result = 1; + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Open the zip file + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($v_result=$this->privOpenFd('wb')) != 1) + { + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Open the temporary file in write mode + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) + { + $this->privCloseFd(); + + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode'); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); + return PclZip::errorCode(); + } + + // ----- Copy the files from the archive to the temporary file + // TBC : Here I should better append the file and go back to erase the central dir + $v_size = filesize($p_archive_filename); + while ($v_size != 0) + { + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read $v_read_size bytes"); + $v_buffer = fread($v_zip_temp_fd, $v_read_size); + @fwrite($this->zip_fd, $v_buffer, $v_read_size); + $v_size -= $v_read_size; + } + + // ----- Close + $this->privCloseFd(); + + // ----- Close the temporary file + @fclose($v_zip_temp_fd); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorLog() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorLog($p_error_code=0, $p_error_string='') + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclError($p_error_code, $p_error_string); + } + else { + $this->error_code = $p_error_code; + $this->error_string = $p_error_string; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privErrorReset() + // Description : + // Parameters : + // -------------------------------------------------------------------------------- + function privErrorReset() + { + if (PCLZIP_ERROR_EXTERNAL == 1) { + PclErrorReset(); + } + else { + $this->error_code = 0; + $this->error_string = ''; + } + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDecrypt() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDecrypt($p_encryption_header, &$p_buffer, $p_size, $p_crc) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDecrypt', "size=".$p_size.""); + $v_result=1; + + // ----- To Be Modified ;-) + $v_pwd = "test"; + + $p_buffer = PclZipUtilZipDecrypt($p_buffer, $p_size, $p_encryption_header, + $p_crc, $v_pwd); + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privDisableMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privDisableMagicQuotes() + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDisableMagicQuotes', ""); + $v_result=1; + + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Look if already done + if ($this->magic_quotes_status != -1) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote already disabled"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Get and memorize the magic_quote value + $this->magic_quotes_status = @get_magic_quotes_runtime(); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Current magic_quotes_runtime status is '".($this->magic_quotes_status==0?'disable':'enable')."'"); + + // ----- Disable magic_quotes + if ($this->magic_quotes_status == 1) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Disable magic_quotes"); + @set_magic_quotes_runtime(0); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : privSwapBackMagicQuotes() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function privSwapBackMagicQuotes() + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privSwapBackMagicQuotes', ""); + $v_result=1; + + // ----- Look if function exists + if ( (!function_exists("get_magic_quotes_runtime")) + || (!function_exists("set_magic_quotes_runtime"))) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Look if something to do + if ($this->magic_quotes_status != -1) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote not modified"); + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + + // ----- Swap back magic_quotes + if ($this->magic_quotes_status == 1) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Enable back magic_quotes"); + @set_magic_quotes_runtime($this->magic_quotes_status); + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + } + // End of class + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathReduction() + // Description : + // Parameters : + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilPathReduction($p_dir) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathReduction", "dir='$p_dir'"); + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + $v_skip = 0; + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + $v_skip++; + } + else if ($v_list[$i] == "") { + // ----- First '/' i.e. root slash + if ($i == 0) { + $v_result = "/".$v_result; + if ($v_skip > 0) { + // ----- It is an invalid path, so the path is not modified + // TBC + $v_result = $p_dir; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid path is unchanged"); + $v_skip = 0; + } + } + // ----- Last '/' i.e. indicates a directory + else if ($i == (sizeof($v_list)-1)) { + $v_result = $v_list[$i]; + } + // ----- Double '/' inside the path + else { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } + } + else { + // ----- Look for item to skip + if ($v_skip > 0) { + $v_skip--; + } + else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } + } + + // ----- Look for skip + if ($v_skip > 0) { + while ($v_skip > 0) { + $v_result = '../'.$v_result; + $v_skip--; + } + } + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilPathInclusion() + // Description : + // This function indicates if the path $p_path is under the $p_dir tree. Or, + // said in an other way, if the file or sub-dir $p_path is inside the dir + // $p_dir. + // The function indicates also if the path is exactly the same as the dir. + // This function supports path with duplicated '/' like '//', but does not + // support '.' or '..' statements. + // Parameters : + // Return Values : + // 0 if $p_path is not inside directory $p_dir + // 1 if $p_path is inside directory $p_dir + // 2 if $p_path is exactly the same as $p_dir + // -------------------------------------------------------------------------------- + function PclZipUtilPathInclusion($p_dir, $p_path) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathInclusion", "dir='$p_dir', path='$p_path'"); + $v_result = 1; + + // ----- Look for path beginning by ./ + if ( ($p_dir == '.') + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) { + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_dir '".$p_dir."'"); + } + if ( ($p_path == '.') + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) { + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_path '".$p_path."'"); + } + + // ----- Explode dir and path by directory separator + $v_list_dir = explode("/", $p_dir); + $v_list_dir_size = sizeof($v_list_dir); + $v_list_path = explode("/", $p_path); + $v_list_path_size = sizeof($v_list_path); + + // ----- Study directories paths + $i = 0; + $j = 0; + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Working on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'"); + + // ----- Look for empty dir (path reduction) + if ($v_list_dir[$i] == '') { + $i++; + continue; + } + if ($v_list_path[$j] == '') { + $j++; + continue; + } + + // ----- Compare the items + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Items ($i,$j) are different"); + $v_result = 0; + } + + // ----- Next items + $i++; + $j++; + } + + // ----- Look if everything seems to be the same + if ($v_result) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break"); + // ----- Skip all the empty items + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++; + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++; + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Looking on dir($i)='".($i < $v_list_dir_size?$v_list_dir[$i]:'')."' and path($j)='".($j < $v_list_path_size?$v_list_path[$j]:'')."'"); + + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) { + // ----- There are exactly the same + $v_result = 2; + } + else if ($i < $v_list_dir_size) { + // ----- The path is shorter than the dir + $v_result = 0; + } + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilCopyBlock() + // Description : + // Parameters : + // $p_mode : read/write compression mode + // 0 : src & dest normal + // 1 : src gzip, dest normal + // 2 : src normal, dest gzip + // 3 : src & dest gzip + // Return Values : + // -------------------------------------------------------------------------------- + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilCopyBlock", "size=$p_size, mode=$p_mode"); + $v_result = 1; + + if ($p_mode==0) + { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset before read :".(@ftell($p_src))); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset before write :".(@ftell($p_dest))); + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = @fread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset after read :".(@ftell($p_src))); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset after write :".(@ftell($p_dest))); + } + else if ($p_mode==1) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = @gzread($p_src, $v_read_size); + @fwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==2) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = @fread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + else if ($p_mode==3) + { + while ($p_size != 0) + { + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE); + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes"); + $v_buffer = @gzread($p_src, $v_read_size); + @gzwrite($p_dest, $v_buffer, $v_read_size); + $p_size -= $v_read_size; + } + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilRename() + // Description : + // This function tries to do a simple rename() function. If it fails, it + // tries to copy the $p_src file in a new $p_dest file and then unlink the + // first one. + // Parameters : + // $p_src : Old filename + // $p_dest : New filename + // Return Values : + // 1 on success, 0 on failure. + // -------------------------------------------------------------------------------- + function PclZipUtilRename($p_src, $p_dest) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilRename", "source=$p_src, destination=$p_dest"); + $v_result = 1; + + // ----- Try to rename the files + if (!@rename($p_src, $p_dest)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to rename file, try copy+unlink"); + + // ----- Try to copy & unlink the src + if (!@copy($p_src, $p_dest)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to copy file"); + $v_result = 0; + } + else if (!@unlink($p_src)) { + //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to unlink old filename"); + $v_result = 0; + } + } + + // ----- Return + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilOptionText() + // Description : + // Translate option value in text. Mainly for debug purpose. + // Parameters : + // $p_option : the option value. + // Return Values : + // The option text value. + // -------------------------------------------------------------------------------- + function PclZipUtilOptionText($p_option) + { + //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilOptionText", "option='".$p_option."'"); + + $v_list = get_defined_constants(); + for (reset($v_list); $v_key = key($v_list); next($v_list)) { + $v_prefix = substr($v_key, 0, 10); + if (( ($v_prefix == 'PCLZIP_OPT') + || ($v_prefix == 'PCLZIP_CB_') + || ($v_prefix == 'PCLZIP_ATT')) + && ($v_list[$v_key] == $p_option)) { + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_key); + return $v_key; + } + } + + $v_result = 'Unknown'; + + //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); + return $v_result; + } + // -------------------------------------------------------------------------------- + + // -------------------------------------------------------------------------------- + // Function : PclZipUtilTranslateWinPath() + // Description : + // Translate windows path by replacing '\' by '/' and optionally removing + // drive letter. + // Parameters : + // $p_path : path to translate. + // $p_remove_disk_letter : true | false + // Return Values : + // The path translated. + // -------------------------------------------------------------------------------- + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true) + { + if (stristr(php_uname(), 'windows')) { + // ----- Look for potential disk letter + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) { + $p_path = substr($p_path, $v_position+1); + } + // ----- Change potential windows directory separator + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) { + $p_path = strtr($p_path, '\\', '/'); + } + } + return $p_path; + } + // -------------------------------------------------------------------------------- + + +?> diff --git a/wp-admin/includes/class-wp-filesystem-direct.php b/wp-admin/includes/class-wp-filesystem-direct.php new file mode 100644 index 0000000..d698b20 --- /dev/null +++ b/wp-admin/includes/class-wp-filesystem-direct.php @@ -0,0 +1,336 @@ +<?php + +class WP_Filesystem_Direct{ + var $permission = null; + var $errors = array(); + function WP_Filesystem_Direct($arg){ + $this->errors = new WP_Error(); + $this->permission = umask(); + } + function connect(){ + return; + } + function setDefaultPermissions($perm){ + $this->permission = $perm; + } + function find_base_dir($base = '.', $echo = false){ + return str_replace('\\','/',ABSPATH); + } + function get_base_dir($base = '.', $echo = false){ + return find_base_dir($base, $echo); + } + function get_contents($file){ + return @file_get_contents($file); + } + function get_contents_array($file){ + return @file($file); + } + function put_contents($file,$contents,$mode=false,$type=''){ + $fp=@fopen($file,'w'.$type); + if (!$fp) + return false; + @fwrite($fp,$contents); + @fclose($fp); + $this->chmod($file,$mode); + return true; + } + function cwd(){ + return @getcwd(); + } + function chgrp($file,$group,$recursive=false){ + if( ! $this->exists($file) ) + return false; + if( ! $recursive ) + return @chgrp($file,$group); + if( ! $this->is_dir($file) ) + return @chgrp($file,$group); + //Is a directory, and we want recursive + $filelist = $this->dirlist($file); + foreach($filelist as $filename){ + $this->chgrp($file.'/'.$filename,$group,$recursive); + } + return true; + } + function chmod($file,$mode=false,$recursive=false){ + if( ! $mode ) + $mode = $this->permission; + if( ! $this->exists($file) ) + return false; + if( ! $recursive ) + return @chmod($file,$mode); + if( ! $this->is_dir($file) ) + return @chmod($file,$mode); + //Is a directory, and we want recursive + $filelist = $this->dirlist($file); + foreach($filelist as $filename){ + $this->chmod($file.'/'.$filename,$mode,$recursive); + } + return true; + } + function chown($file,$owner,$recursive=false){ + if( ! $this->exists($file) ) + return false; + if( ! $recursive ) + return @chown($file,$owner); + if( ! $this->is_dir($file) ) + return @chown($file,$owner); + //Is a directory, and we want recursive + $filelist = $this->dirlist($file); + foreach($filelist as $filename){ + $this->chown($file.'/'.$filename,$owner,$recursive); + } + return true; + } + function owner($file){ + $owneruid=@fileowner($file); + if( ! $owneruid ) + return false; + if( !function_exists('posix_getpwuid') ) + return $owneruid; + $ownerarray=posix_getpwuid($owneruid); + return $ownerarray['name']; + } + function getchmod($file){ + return @fileperms($file); + } + function gethchmod($file){ + //From the PHP.net page for ...? + $perms = $this->getchmod($file); + if (($perms & 0xC000) == 0xC000) { + // Socket + $info = 's'; + } elseif (($perms & 0xA000) == 0xA000) { + // Symbolic Link + $info = 'l'; + } elseif (($perms & 0x8000) == 0x8000) { + // Regular + $info = '-'; + } elseif (($perms & 0x6000) == 0x6000) { + // Block special + $info = 'b'; + } elseif (($perms & 0x4000) == 0x4000) { + // Directory + $info = 'd'; + } elseif (($perms & 0x2000) == 0x2000) { + // Character special + $info = 'c'; + } elseif (($perms & 0x1000) == 0x1000) { + // FIFO pipe + $info = 'p'; + } else { + // Unknown + $info = 'u'; + } + + // Owner + $info .= (($perms & 0x0100) ? 'r' : '-'); + $info .= (($perms & 0x0080) ? 'w' : '-'); + $info .= (($perms & 0x0040) ? + (($perms & 0x0800) ? 's' : 'x' ) : + (($perms & 0x0800) ? 'S' : '-')); + + // Group + $info .= (($perms & 0x0020) ? 'r' : '-'); + $info .= (($perms & 0x0010) ? 'w' : '-'); + $info .= (($perms & 0x0008) ? + (($perms & 0x0400) ? 's' : 'x' ) : + (($perms & 0x0400) ? 'S' : '-')); + + // World + $info .= (($perms & 0x0004) ? 'r' : '-'); + $info .= (($perms & 0x0002) ? 'w' : '-'); + $info .= (($perms & 0x0001) ? + (($perms & 0x0200) ? 't' : 'x' ) : + (($perms & 0x0200) ? 'T' : '-')); + return $info; + } + function getnumchmodfromh($mode) { + $realmode = ""; + $legal = array("","w","r","x","-"); + $attarray = preg_split("//",$mode); + for($i=0;$i<count($attarray);$i++){ + if($key = array_search($attarray[$i],$legal)){ + $realmode .= $legal[$key]; + } + } + $mode = str_pad($realmode,9,'-'); + $trans = array('-'=>'0','r'=>'4','w'=>'2','x'=>'1'); + $mode = strtr($mode,$trans); + $newmode = ''; + $newmode .= $mode[0]+$mode[1]+$mode[2]; + $newmode .= $mode[3]+$mode[4]+$mode[5]; + $newmode .= $mode[6]+$mode[7]+$mode[8]; + return $newmode; + } + function group($file){ + $gid=@filegroup($file); + if( ! $gid ) + return false; + if( !function_exists('posix_getgrgid') ) + return $gid; + $grouparray=posix_getgrgid($gid); + return $grouparray['name']; + } + + function copy($source,$destination,$overwrite=false){ + if( $overwrite && $this->exists($destination) ) + return false; + return copy($source,$destination); + } + + function move($source,$destination,$overwrite=false){ + //Possible to use rename() + if( $this->copy($source,$destination,$overwrite) && $this->exists($destination) ){ + $this->delete($source); + return true; + } else { + return false; + } + } + + function delete($file,$recursive=false){ + $file = str_replace('\\','/',$file); //for win32, occasional problems deleteing files otherwise + + if( $this->is_file($file) ) + return @unlink($file); + + if( !$recursive && $this->is_dir($file) ) + return @rmdir($file); + + $filelist = $this->dirlist($file); + if( ! $filelist ) + return true; //No files exist, Say we've deleted them + + $retval = true; + foreach($filelist as $filename=>$fileinfo){ + if( ! $this->delete($file.'/'.$filename,$recursive) ) + $retval = false; + } + if( ! @rmdir($file) ) + return false; + return $retval; + } + + function exists($file){ + return @file_exists($file); + } + + function is_file($file){ + return @is_file($file); + } + + function is_dir($path){ + return @is_dir($path); + } + + function is_readable($file){ + return @is_readable($file); + } + + function is_writable($file){ + return @is_writable($file); + } + + function atime($file){ + return @fileatime($file); + } + + function mtime($file){ + return @filemtime($file); + } + function size($file){ + return @filesize($file); + } + + function touch($file,$time=0,$atime=0){ + if($time==0) + $time = time(); + if($atime==0) + $atime = time(); + return @touch($file,$time,$atime); + } + + function mkdir($path,$chmod=false,$chown=false,$chgrp=false){ + if( ! $chmod) + $chmod = $this->permission; + + if( !@mkdir($path,$chmod) ) + return false; + if( $chown ) + $this->chown($path,$chown); + if( $chgrp ) + $this->chgrp($path,$chgrp); + return true; + } + + function rmdir($path,$recursive=false){ + if( ! $recursive ) + return @rmdir($path); + //recursive: + $filelist = $this->dirlist($path); + foreach($filelist as $filename=>$det){ + if ( '/' == substr($filename,-1,1) ) + $this->rmdir($path.'/'.$filename,$recursive); + @rmdir($filename); + } + return @rmdir($path); + } + + function dirlist($path,$incdot=false,$recursive=false){ + if( $this->is_file($path) ){ + $limitFile = basename($path); + $path = dirname($path); + } else { + $limitFile = false; + } + if( ! $this->is_dir($path) ) + return false; + + $ret = array(); + $dir = dir($path); + while (false !== ($entry = $dir->read())) { + $struc = array(); + $struc['name'] = $entry; + + if( '.' == $struc['name'][0] && !$incdot) + continue; + if( $limitFile && $struc['name'] != $limitFile) + continue; + + $struc['perms'] = $this->gethchmod($path.'/'.$entry); + $struc['permsn'] = $this->getnumchmodfromh($struc['perms']); + $struc['number'] = false; + $struc['owner'] = $this->owner($path.'/'.$entry); + $struc['group'] = $this->group($path.'/'.$entry); + $struc['size'] = $this->size($path.'/'.$entry); + $struc['lastmodunix']= $this->mtime($path.'/'.$entry); + $struc['lastmod'] = date('M j',$struc['lastmodunix']); + $struc['time'] = date('h:i:s',$struc['lastmodunix']); + $struc['type'] = $this->is_dir($path.'/'.$entry) ? 'd' : 'f'; + if ('d' == $struc['type'] ){ + $struc['files'] = array(); + + if( $incdot ){ + //We're including the doted starts + if( '.' != $struc['name'] && '..' != $struc['name'] ){ //Ok, It isnt a special folder + if ($recursive) + $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive); + } + } else { //No dots + if ($recursive) + $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive); + } + } + //File + $ret[$struc['name']] = $struc; + } + $dir->close(); + unset($dir); + return $ret; + } + + function __destruct(){ + return; + } +} +?> diff --git a/wp-admin/includes/class-wp-filesystem-ftpext.php b/wp-admin/includes/class-wp-filesystem-ftpext.php new file mode 100644 index 0000000..a8a3585 --- /dev/null +++ b/wp-admin/includes/class-wp-filesystem-ftpext.php @@ -0,0 +1,480 @@ +<?php +class WP_Filesystem_FTPext{ + var $link; + var $timeout = 5; + var $errors = array(); + var $options = array(); + + var $wp_base = ''; + var $permission = null; + + var $filetypes = array( + 'php'=>FTP_ASCII, + 'css'=>FTP_ASCII, + 'txt'=>FTP_ASCII, + 'js'=>FTP_ASCII, + 'html'=>FTP_ASCII, + 'htm'=>FTP_ASCII, + 'xml'=>FTP_ASCII, + + 'jpg'=>FTP_BINARY, + 'png'=>FTP_BINARY, + 'gif'=>FTP_BINARY, + 'bmp'=>FTP_BINARY + ); + + function WP_Filesystem_FTPext($opt='') { + $this->errors = new WP_Error(); + + //Check if possible to use ftp functions. + if ( ! extension_loaded('ftp') ) { + $this->errors->add('no_ftp_ext', __('The ftp PHP extension is not available')); + return false; + } + + // Set defaults: + if ( empty($opt['port']) ) + $this->options['port'] = 21; + else + $this->options['port'] = $opt['port']; + + if ( empty($opt['hostname']) ) + $this->errors->add('empty_hostname', __('FTP hostname is required')); + else + $this->options['hostname'] = $opt['hostname']; + + if ( isset($opt['base']) && ! empty($opt['base']) ) + $this->wp_base = $opt['base']; + + // Check if the options provided are OK. + if ( empty ($opt['username']) ) + $this->errors->add('empty_username', __('FTP username is required')); + else + $this->options['username'] = $opt['username']; + + if ( empty ($opt['password']) ) + $this->errors->add('empty_password', __('FTP password is required')); + else + $this->options['password'] = $opt['password']; + + $this->options['ssl'] = ( !empty($opt['ssl']) ); + } + + function connect(){ + if ( $this->options['ssl'] && function_exists('ftp_ssl_connect') ) { + $this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'],$this->timeout); + } else { + $this->link = @ftp_connect($this->options['hostname'], $this->options['port'],$this->timeout); + } + + if ( ! $this->link ) { + $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port'])); + return false; + } + + if ( ! @ftp_login($this->link,$this->options['username'], $this->options['password']) ) { + $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username'])); + return false; + } + + return true; + } + + function setDefaultPermissions($perm){ + $this->permission = $perm; + } + + function find_base_dir($base = '.',$echo = false){ + $abspath = str_replace('\\','/',ABSPATH); //windows: Straighten up the paths.. + if( strpos($abspath, ':') ){ //Windows, Strip out the driveletter + if( preg_match("|.{1}\:(.+)|i", $abspath, $mat) ) + $abspath = $mat[1]; + } + + if( empty( $base ) || '.' == $base ) $base = $this->cwd(); + if( empty( $base ) ) $base = '/'; + if( '/' != substr($base, -1) ) $base .= '/'; + + if($echo) echo __('Changing to ') . $base .'<br>'; + if( false === $this->chdir($base) ) + return false; + + if( $this->exists($base . 'wp-settings.php') ){ + if($echo) echo __('Found ') . $base . 'wp-settings.php<br>'; + $this->wp_base = $base; + return $this->wp_base; + } + + if( strpos($abspath, $base) > 0) + $arrPath = split('/',substr($abspath,strpos($abspath, $base))); + else + $arrPath = split('/',$abspath); + + for($i = 0; $i <= count($arrPath); $i++) + if( $arrPath[ $i ] == '' ) unset( $arrPath[ $i ] ); + + foreach($arrPath as $key=>$folder){ + if( $this->is_dir($base . $folder) ){ + if($echo) echo __('Found ') . $folder . ' ' . __('Changing to') . ' ' . $base . $folder . '/<br>'; + return $this->find_base_dir($base . $folder . '/',$echo); + } + } + + if( $base == '/' ) + return false; + //If we get this far, somethings gone wrong, change to / and restart the process. + return $this->find_base_dir('/',$echo); + } + function get_base_dir($base = '.', $echo=false){ + if( empty($this->wp_base) ) + $this->wp_base = $this->find_base_dir($base,$echo); + return $this->wp_base; + } + function get_contents($file,$type='',$resumepos=0){ + if( empty($type) ){ + $extension = substr(strrchr($file, "."), 1); + $type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_ASCII; + } + $temp = tmpfile(); + if( ! @ftp_fget($this->link,$temp,$file,$type,$resumepos) ) + return false; + fseek($temp, 0); //Skip back to the start of the file being written to + $contents = ''; + while (!feof($temp)) { + $contents .= fread($temp, 8192); + } + fclose($temp); + return $contents; + } + function get_contents_array($file){ + return explode("\n",$this->get_contents($file)); + } + function put_contents($file,$contents,$type=''){ + if( empty($type) ){ + $extension = substr(strrchr($filename, "."), 1); + $type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_ASCII; + } + $temp = tmpfile(); + fwrite($temp,$contents); + fseek($temp, 0); //Skip back to the start of the file being written to + $ret = @ftp_fput($this->link,$file,$temp,$type); + fclose($temp); + return $ret; + } + function cwd(){ + return ftp_pwd($this->link); + } + function chdir($dir){ + return @ftp_chdir($dir); + } + function chgrp($file,$group,$recursive=false){ + return false; + } + function chmod($file,$mode=false,$recursive=false){ + if( ! $mode ) + $mode = $this->permission; + if( ! $mode ) + return false; + if ( ! $this->exists($file) ) + return false; + if ( ! $recursive || ! $this->is_dir($file) ){ + if (!function_exists('ftp_chmod')) + return @ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file)); + return @ftp_chmod($this->link,$mode,$file); + } + //Is a directory, and we want recursive + $filelist = $this->dirlist($file); + foreach($filelist as $filename){ + $this->chmod($file.'/'.$filename,$mode,$recursive); + } + return true; + } + function chown($file,$owner,$recursive=false){ + return false; + } + function owner($file){ + $dir = $this->dirlist($file); + return $dir[$file]['owner']; + } + function getchmod($file){ + $dir = $this->dirlist($file); + return $dir[$file]['permsn']; + } + function gethchmod($file){ + //From the PHP.net page for ...? + $perms = $this->getchmod($file); + if (($perms & 0xC000) == 0xC000) { + // Socket + $info = 's'; + } elseif (($perms & 0xA000) == 0xA000) { + // Symbolic Link + $info = 'l'; + } elseif (($perms & 0x8000) == 0x8000) { + // Regular + $info = '-'; + } elseif (($perms & 0x6000) == 0x6000) { + // Block special + $info = 'b'; + } elseif (($perms & 0x4000) == 0x4000) { + // Directory + $info = 'd'; + } elseif (($perms & 0x2000) == 0x2000) { + // Character special + $info = 'c'; + } elseif (($perms & 0x1000) == 0x1000) { + // FIFO pipe + $info = 'p'; + } else { + // Unknown + $info = 'u'; + } + + // Owner + $info .= (($perms & 0x0100) ? 'r' : '-'); + $info .= (($perms & 0x0080) ? 'w' : '-'); + $info .= (($perms & 0x0040) ? + (($perms & 0x0800) ? 's' : 'x' ) : + (($perms & 0x0800) ? 'S' : '-')); + + // Group + $info .= (($perms & 0x0020) ? 'r' : '-'); + $info .= (($perms & 0x0010) ? 'w' : '-'); + $info .= (($perms & 0x0008) ? + (($perms & 0x0400) ? 's' : 'x' ) : + (($perms & 0x0400) ? 'S' : '-')); + + // World + $info .= (($perms & 0x0004) ? 'r' : '-'); + $info .= (($perms & 0x0002) ? 'w' : '-'); + $info .= (($perms & 0x0001) ? + (($perms & 0x0200) ? 't' : 'x' ) : + (($perms & 0x0200) ? 'T' : '-')); + return $info; + } + function getnumchmodfromh($mode) { + $realmode = ""; + $legal = array("","w","r","x","-"); + $attarray = preg_split("//",$mode); + for($i=0;$i<count($attarray);$i++){ + if($key = array_search($attarray[$i],$legal)){ + $realmode .= $legal[$key]; + } + } + $mode = str_pad($realmode,9,'-'); + $trans = array('-'=>'0','r'=>'4','w'=>'2','x'=>'1'); + $mode = strtr($mode,$trans); + $newmode = ''; + $newmode .= $mode[0]+$mode[1]+$mode[2]; + $newmode .= $mode[3]+$mode[4]+$mode[5]; + $newmode .= $mode[6]+$mode[7]+$mode[8]; + return $newmode; + } + function group($file){ + $dir = $this->dirlist($file); + return $dir[$file]['group']; + } + function copy($source,$destination,$overwrite=false){ + if( ! $overwrite && $this->exists($destination) ) + return false; + $content = $this->get_contents($source); + if( false === $content) + return false; + return $this->put_contents($destination,$content); + } + function move($source,$destination,$overwrite=false){ + return ftp_rename($this->link,$source,$destination); + } + + function delete($file,$recursive=false) { + if ( $this->is_file($file) ) + return @ftp_delete($this->link,$file); + if ( !$recursive ) + return @ftp_rmdir($this->link,$file); + $filelist = $this->dirlist($file); + foreach ((array) $filelist as $filename => $fileinfo) { + $this->delete($file.'/'.$filename,$recursive); + } + return @ftp_rmdir($this->link,$file); + } + + function exists($file){ + $list = ftp_rawlist($this->link,$file,false); + if( ! $list ) + return false; + return count($list) == 1 ? true : false; + } + function is_file($file){ + return $this->is_dir($file) ? false : true; + } + function is_dir($path){ + $cwd = $this->cwd(); + @ftp_chdir($this->link, $path); + if ( $this->cwd() != $cwd ) { + @ftp_chdir($this->link, $cwd); + return true; + } + return false; + } + function is_readable($file){ + //Get dir list, Check if the file is writable by the current user?? + return true; + } + function is_writable($file){ + //Get dir list, Check if the file is writable by the current user?? + return true; + } + function atime($file){ + return false; + } + function mtime($file){ + return ftp_mdtm($this->link, $file); + } + function size($file){ + return ftp_size($this->link, $file); + } + function touch($file,$time=0,$atime=0){ + return false; + } + function mkdir($path,$chmod=false,$chown=false,$chgrp=false){ + if( !@ftp_mkdir($this->link, $path) ) + return false; + if( $chmod ) + $this->chmod($path, $chmod); + if( $chown ) + $this->chown($path, $chown); + if( $chgrp ) + $this->chgrp($path, $chgrp); + return true; + } + function rmdir($path,$recursive=false){ + if( ! $recursive ) + return @ftp_rmdir($this->link, $path); + + //TODO: Recursive Directory delete, Have to delete files from the folder first. + //$dir = $this->dirlist($path); + //foreach($dir as $file) + + } + + function parselisting($line) { + $is_windows = ($this->OS_remote == FTP_OS_Windows); + if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/",$line,$lucifer)) { + $b = array(); + if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix + $b['isdir'] = ($lucifer[7]=="<DIR>"); + if ( $b['isdir'] ) + $b['type'] = 'd'; + else + $b['type'] = 'f'; + $b['size'] = $lucifer[7]; + $b['month'] = $lucifer[1]; + $b['day'] = $lucifer[2]; + $b['year'] = $lucifer[3]; + $b['hour'] = $lucifer[4]; + $b['minute'] = $lucifer[5]; + $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]); + $b['am/pm'] = $lucifer[6]; + $b['name'] = $lucifer[8]; + } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) { + //echo $line."\n"; + $lcount=count($lucifer); + if ($lcount<8) return ''; + $b = array(); + $b['isdir'] = $lucifer[0]{0} === "d"; + $b['islink'] = $lucifer[0]{0} === "l"; + if ( $b['isdir'] ) + $b['type'] = 'd'; + elseif ( $b['islink'] ) + $b['type'] = 'l'; + else + $b['type'] = 'f'; + $b['perms'] = $lucifer[0]; + $b['number'] = $lucifer[1]; + $b['owner'] = $lucifer[2]; + $b['group'] = $lucifer[3]; + $b['size'] = $lucifer[4]; + if ($lcount==8) { + sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']); + sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']); + $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']); + $b['name'] = $lucifer[7]; + } else { + $b['month'] = $lucifer[5]; + $b['day'] = $lucifer[6]; + if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) { + $b['year'] = date("Y"); + $b['hour'] = $l2[1]; + $b['minute'] = $l2[2]; + } else { + $b['year'] = $lucifer[7]; + $b['hour'] = 0; + $b['minute'] = 0; + } + $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute'])); + $b['name'] = $lucifer[8]; + } + } + + return $b; + } + + function dirlist($path='.',$incdot=false,$recursive=false){ + if( $this->is_file($path) ){ + $limitFile = basename($path); + $path = dirname($path) . '/'; + } else { + $limitFile = false; + } + //if( ! $this->is_dir($path) ) + // return false; + $list = ftp_rawlist($this->link , '-a ' . $path, false); + if ( $list === false ) + return false; + + $dirlist = array(); + foreach ( $list as $k => $v ) { + $entry = $this->parselisting($v); + if ( empty($entry) ) + continue; + + if ( $entry["name"]=="." or $entry["name"]==".." ) + continue; + + $dirlist[$entry['name']] = $entry; + } + + if ( ! $dirlist ) + return false; + if ( empty($dirlist) ) + return array(); + + $ret = array(); + foreach ( $dirlist as $struc ) { + + if ( 'd' == $struc['type'] ) { + $struc['files'] = array(); + + if ( $incdot ){ + //We're including the doted starts + if( '.' != $struc['name'] && '..' != $struc['name'] ){ //Ok, It isnt a special folder + if ($recursive) + $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive); + } + } else { //No dots + if ($recursive) + $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive); + } + } + //File + $ret[$struc['name']] = $struc; + } + return $ret; + } + + function __destruct(){ + if( $this->link ) + ftp_close($this->link); + } +} + +?> diff --git a/wp-admin/includes/class-wp-filesystem-ftpsockets.php b/wp-admin/includes/class-wp-filesystem-ftpsockets.php new file mode 100644 index 0000000..15ab390 --- /dev/null +++ b/wp-admin/includes/class-wp-filesystem-ftpsockets.php @@ -0,0 +1,426 @@ +<?php +class WP_Filesystem_ftpsockets{ + var $ftp = false; + var $timeout = 5; + var $errors; + var $options = array(); + + var $wp_base = ''; + var $permission = null; + + var $filetypes = array( + 'php'=>FTP_ASCII, + 'css'=>FTP_ASCII, + 'txt'=>FTP_ASCII, + 'js'=>FTP_ASCII, + 'html'=>FTP_ASCII, + 'htm'=>FTP_ASCII, + 'xml'=>FTP_ASCII, + + 'jpg'=>FTP_BINARY, + 'png'=>FTP_BINARY, + 'gif'=>FTP_BINARY, + 'bmp'=>FTP_BINARY + ); + + function WP_Filesystem_ftpsockets($opt='') { + $this->errors = new WP_Error(); + + //Check if possible to use ftp functions. + if( ! @include_once ABSPATH . 'wp-admin/includes/class-ftp.php' ) + return false; + $this->ftp = new ftp(); + + //Set defaults: + if ( empty($opt['port']) ) + $this->options['port'] = 21; + else + $this->options['port'] = $opt['port']; + + if ( empty($opt['hostname']) ) + $this->errors->add('empty_hostname', __('FTP hostname is required')); + else + $this->options['hostname'] = $opt['hostname']; + + if ( isset($opt['base']) && ! empty($opt['base']) ) + $this->wp_base = $opt['base']; + + // Check if the options provided are OK. + if ( empty ($opt['username']) ) + $this->errors->add('empty_username', __('FTP username is required')); + else + $this->options['username'] = $opt['username']; + + if ( empty ($opt['password']) ) + $this->errors->add('empty_password', __('FTP password is required')); + else + $this->options['password'] = $opt['password']; + } + + function connect() { + if ( ! $this->ftp ) + return false; + + //$this->ftp->Verbose = true; + + if ( ! $this->ftp->SetServer($this->options['hostname'], $this->options['port']) ) { + $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port'])); + return false; + } + if ( ! $this->ftp->connect() ) { + $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port'])); + return false; + } + + if ( ! $this->ftp->login($this->options['username'], $this->options['password']) ) { + $this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username'])); + return false; + } + + $this->ftp->SetType(FTP_AUTOASCII); + $this->ftp->Passive(true); + return true; + } + + function setDefaultPermissions($perm) { + $this->permission = $perm; + } + + function find_base_dir($base = '.',$echo = false) { + $abspath = str_replace('\\','/',ABSPATH); //windows: Straighten up the paths.. + if( strpos($abspath, ':') ){ //Windows, Strip out the driveletter + if( preg_match("|.{1}\:(.+)|i", $abspath, $mat) ) + $abspath = $mat[1]; + } + + if( empty( $base ) || '.' == $base ) $base = $this->cwd(); + if( empty( $base ) ) $base = '/'; + if( '/' != substr($base, -1) ) $base .= '/'; + + if($echo) echo __('Changing to ') . $base .'<br>'; + if( false === $this->chdir($base) ) + return false; + + if( $this->exists($base . 'wp-settings.php') ){ + if($echo) echo __('Found ') . $base . 'wp-settings.php<br>'; + $this->wp_base = $base; + return $this->wp_base; + } + + if( strpos($abspath, $base) > 0) + $arrPath = split('/',substr($abspath,strpos($abspath, $base))); + else + $arrPath = split('/',$abspath); + + for($i = 0; $i <= count($arrPath); $i++) + if( $arrPath[ $i ] == '' ) unset( $arrPath[ $i ] ); + + foreach($arrPath as $key=>$folder){ + if( $this->is_dir($base . $folder) ){ + if($echo) echo __('Found ') . $folder . ' ' . __('Changing to') . ' ' . $base . $folder . '/<br>'; + return $this->find_base_dir($base . $folder . '/',$echo); + } + } + + if( $base == '/' ) + return false; + //If we get this far, somethings gone wrong, change to / and restart the process. + return $this->find_base_dir('/',$echo); + } + + function get_base_dir($base = '.', $echo = false){ + if( empty($this->wp_base) ) + $this->wp_base = $this->find_base_dir($base, $echo); + return $this->wp_base; + } + + function get_contents($file,$type='',$resumepos=0){ + if( ! $this->exists($file) ) + return false; + + if( empty($type) ){ + $extension = substr(strrchr($file, "."), 1); + $type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_AUTOASCII; + } + $this->ftp->SetType($type); + $temp = tmpfile(); + if ( ! $this->ftp->fget($temp, $file) ) { + fclose($temp); + return ''; //Blank document, File does exist, Its just blank. + } + fseek($temp, 0); //Skip back to the start of the file being written to + $contents = ''; + while ( !feof($temp) ) + $contents .= fread($temp, 8192); + fclose($temp); + return $contents; + } + + function get_contents_array($file){ + return explode("\n",$this->get_contents($file)); + } + + function put_contents($file,$contents,$type=''){ + if( empty($type) ){ + $extension = substr(strrchr($file, "."), 1); + $type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_ASCII; + } + $this->ftp->SetType($type); + + $temp = tmpfile(); + fwrite($temp,$contents); + fseek($temp, 0); //Skip back to the start of the file being written to + $ret = $this->ftp->fput($file, $temp); + fclose($temp); + return $ret; + } + + function cwd(){ + return $this->ftp->pwd(); + } + + function chdir($file){ + return $this->ftp->chdir($file); + } + + function chgrp($file,$group,$recursive=false){ + return false; + } + + function chmod($file,$mode=false,$recursive=false){ + if( ! $mode ) + $mode = $this->permission; + if( ! $mode ) + return false; + //if( ! $this->exists($file) ) + // return false; + if( ! $recursive || ! $this->is_dir($file) ){ + return $this->ftp->chmod($file,$mode); + } + //Is a directory, and we want recursive + $filelist = $this->dirlist($file); + foreach($filelist as $filename){ + $this->chmod($file.'/'.$filename,$mode,$recursive); + } + return true; + } + + function chown($file,$owner,$recursive=false){ + return false; + } + + function owner($file){ + $dir = $this->dirlist($file); + return $dir[$file]['owner']; + } + + function getchmod($file){ + $dir = $this->dirlist($file); + return $dir[$file]['permsn']; + } + + function gethchmod($file){ + //From the PHP.net page for ...? + $perms = $this->getchmod($file); + if (($perms & 0xC000) == 0xC000) { + // Socket + $info = 's'; + } elseif (($perms & 0xA000) == 0xA000) { + // Symbolic Link + $info = 'l'; + } elseif (($perms & 0x8000) == 0x8000) { + // Regular + $info = '-'; + } elseif (($perms & 0x6000) == 0x6000) { + // Block special + $info = 'b'; + } elseif (($perms & 0x4000) == 0x4000) { + // Directory + $info = 'd'; + } elseif (($perms & 0x2000) == 0x2000) { + // Character special + $info = 'c'; + } elseif (($perms & 0x1000) == 0x1000) { + // FIFO pipe + $info = 'p'; + } else { + // Unknown + $info = 'u'; + } + + // Owner + $info .= (($perms & 0x0100) ? 'r' : '-'); + $info .= (($perms & 0x0080) ? 'w' : '-'); + $info .= (($perms & 0x0040) ? + (($perms & 0x0800) ? 's' : 'x' ) : + (($perms & 0x0800) ? 'S' : '-')); + + // Group + $info .= (($perms & 0x0020) ? 'r' : '-'); + $info .= (($perms & 0x0010) ? 'w' : '-'); + $info .= (($perms & 0x0008) ? + (($perms & 0x0400) ? 's' : 'x' ) : + (($perms & 0x0400) ? 'S' : '-')); + + // World + $info .= (($perms & 0x0004) ? 'r' : '-'); + $info .= (($perms & 0x0002) ? 'w' : '-'); + $info .= (($perms & 0x0001) ? + (($perms & 0x0200) ? 't' : 'x' ) : + (($perms & 0x0200) ? 'T' : '-')); + return $info; + } + + function getnumchmodfromh($mode) { + $realmode = ""; + $legal = array("","w","r","x","-"); + $attarray = preg_split("//",$mode); + for($i=0;$i<count($attarray);$i++){ + if($key = array_search($attarray[$i],$legal)){ + $realmode .= $legal[$key]; + } + } + $mode = str_pad($realmode,9,'-'); + $trans = array('-'=>'0','r'=>'4','w'=>'2','x'=>'1'); + $mode = strtr($mode,$trans); + $newmode = ''; + $newmode .= $mode[0]+$mode[1]+$mode[2]; + $newmode .= $mode[3]+$mode[4]+$mode[5]; + $newmode .= $mode[6]+$mode[7]+$mode[8]; + return $newmode; + } + + function group($file){ + $dir = $this->dirlist($file); + return $dir[$file]['group']; + } + + function copy($source,$destination,$overwrite=false){ + if( ! $overwrite && $this->exists($destination) ) + return false; + + $content = $this->get_contents($source); + if ( false === $content ) + return false; + + return $this->put_contents($destination,$content); + } + + function move($source,$destination,$overwrite=false){ + return $this->ftp->rename($source,$destination); + } + + function delete($file,$recursive=false) { + if ( $this->is_file($file) ) + return $this->ftp->delete($file); + if ( !$recursive ) + return $this->ftp->rmdir($file); + + return $this->ftp->mdel($file); + } + + function exists($file){ + return $this->ftp->is_exists($file); + } + + function is_file($file){ + return $this->is_dir($file) ? false : true; + } + + function is_dir($path){ + $cwd = $this->cwd(); + if ( $this->chdir($path) ) { + $this->chdir($cwd); + return true; + } + return false; + } + + function is_readable($file){ + //Get dir list, Check if the file is writable by the current user?? + return true; + } + + function is_writable($file){ + //Get dir list, Check if the file is writable by the current user?? + return true; + } + + function atime($file){ + return false; + } + + function mtime($file){ + return $this->ftp->mdtm($file); + } + + function size($file){ + return $this->ftp->filesize($file); + } + + function touch($file,$time=0,$atime=0){ + return false; + } + + function mkdir($path,$chmod=false,$chown=false,$chgrp=false){ + if( ! $this->ftp->mkdir($path) ) + return false; + if( $chmod ) + $this->chmod($path, $chmod); + if( $chown ) + $this->chown($path, $chown); + if( $chgrp ) + $this->chgrp($path, $chgrp); + return true; + } + + function rmdir($path,$recursive=false){ + if( ! $recursive ) + return $this->ftp->rmdir($path); + + return $this->ftp->mdel($path); + } + + function dirlist($path='.',$incdot=false,$recursive=false){ + if( $this->is_file($path) ){ + $limitFile = basename($path); + $path = dirname($path) . '/'; + } else { + $limitFile = false; + } + //if( ! $this->is_dir($path) ) + // return false; + $list = $this->ftp->dirlist($path); + if( ! $list ) + return false; + if( empty($list) ) + return array(); + + $ret = array(); + foreach ( $list as $struc ) { + + if ( 'd' == $struc['type'] ) { + $struc['files'] = array(); + + if ( $incdot ){ + //We're including the doted starts + if( '.' != $struc['name'] && '..' != $struc['name'] ){ //Ok, It isnt a special folder + if ($recursive) + $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive); + } + } else { //No dots + if ($recursive) + $struc['files'] = $this->dirlist($path.'/'.$struc['name'],$incdot,$recursive); + } + } + //File + $ret[$struc['name']] = $struc; + } + return $ret; + } + + function __destruct(){ + $this->ftp->quit(); + } +} +?> diff --git a/wp-admin/includes/dashboard.php b/wp-admin/includes/dashboard.php new file mode 100644 index 0000000..c675c4d --- /dev/null +++ b/wp-admin/includes/dashboard.php @@ -0,0 +1,538 @@ +<?php + +// Registers dashboard widgets, handles POST data, sets up filters +function wp_dashboard_setup() { + global $wpdb, $wp_dashboard_sidebars; + $update = false; + if ( !$widget_options = get_option( 'dashboard_widget_options' ) ) + $widget_options = array(); + + + /* Register WP Dashboard Dynamic Sidebar */ + register_sidebar( array( + 'name' => 'WordPress Dashboard', + 'id' => 'wp_dashboard', + 'before_widget' => "\t<div class='dashboard-widget-holder %2\$s' id='%1\$s'>\n\n\t\t<div class='dashboard-widget'>\n\n", + 'after_widget' => "\t\t</div>\n\n\t</div>\n\n", + 'before_title' => "\t\t\t<h3 class='dashboard-widget-title'>", + 'after_title' => "</h3>\n\n" + ) ); + + + /* Register Widgets and Controls */ + + // Recent Comments Widget + if ( current_user_can( 'moderate_comments' ) && $mod_comments = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = '0'") ) { + $notice = sprintf( __ngettext( '%d comment awaiting moderation', '%d comments awaiting moderation', $mod_comments ), $mod_comments ); + $notice = "<a href='moderation.php'>$notice</a>"; + } else { + $notice = ''; + } + wp_register_sidebar_widget( 'dashboard_recent_comments', __( 'Recent Comments' ), 'wp_dashboard_recent_comments', + array( 'all_link' => 'edit-comments.php', 'notice' => $notice, 'width' => 'half' ) + ); + + // Incoming Links Widget + if ( !isset( $widget_options['dashboard_incoming_links'] ) ) { + $update = true; + $widget_options['dashboard_incoming_links'] = array( + 'link' => apply_filters( 'dashboard_incoming_links_link', 'http://blogsearch.google.com/blogsearch?hl=en&scoring=d&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ), + 'url' => apply_filters( 'dashboard_incoming_links_feed', 'http://blogsearch.google.com/blogsearch_feeds?hl=en&scoring=d&ie=utf-8&num=10&output=rss&partner=wordpress&q=link:' . trailingslashit( get_option('home') ) ), + 'items' => 5, + 'show_date' => 0 + ); + } + wp_register_sidebar_widget( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_empty', + array( 'all_link' => $widget_options['dashboard_incoming_links']['link'], 'feed_link' => $widget_options['dashboard_incoming_links']['url'], 'width' => 'half' ), + 'wp_dashboard_cached_rss_widget', 'wp_dashboard_incoming_links_output' + ); + wp_register_widget_control( 'dashboard_incoming_links', __( 'Incoming Links' ), 'wp_dashboard_rss_control', array(), + array( 'widget_id' => 'dashboard_incoming_links', 'form_inputs' => array( 'title' => false, 'show_summary' => false, 'show_author' => false ) ) + ); + + + // WP Plugins Widget + wp_register_sidebar_widget( 'dashboard_plugins', __( 'Plugins' ), 'wp_dashboard_empty', + array( 'all_link' => 'http://wordpress.org/extend/plugins/', 'feed_link' => 'http://wordpress.org/extend/plugins/rss/topics/', 'width' => 'half' ), + 'wp_dashboard_cached_rss_widget', 'wp_dashboard_plugins_output', + array( 'http://wordpress.org/extend/plugins/rss/browse/popular/', 'http://wordpress.org/extend/plugins/rss/browse/new/', 'http://wordpress.org/extend/plugins/rss/browse/updated/' ) + ); + + // Primary feed (Dev Blog) Widget + if ( !isset( $widget_options['dashboard_primary'] ) ) { + $update = true; + $widget_options['dashboard_primary'] = array( + 'link' => apply_filters( 'dashboard_primary_link', 'http://wordpress.org/development/' ), + 'url' => apply_filters( 'dashboard_primary_feed', 'http://wordpress.org/development/feed/' ), + 'title' => apply_filters( 'dashboard_primary_title', __( 'WordPress Development Blog' ) ), + 'items' => 2, + 'show_summary' => 1, + 'show_author' => 0, + 'show_date' => 1 + ); + } + wp_register_sidebar_widget( 'dashboard_primary', $widget_options['dashboard_primary']['title'], 'wp_dashboard_empty', + array( 'all_link' => $widget_options['dashboard_primary']['link'], 'feed_link' => $widget_options['dashboard_primary']['url'], 'width' => 'half', 'class' => 'widget_rss' ), + 'wp_dashboard_cached_rss_widget', 'wp_dashboard_rss_output' + ); + wp_register_widget_control( 'dashboard_primary', __( 'Primary Feed' ), 'wp_dashboard_rss_control', array(), + array( 'widget_id' => 'dashboard_primary' ) + ); + + + // Secondary Feed (Planet) Widget + if ( !isset( $widget_options['dashboard_secondary'] ) ) { + $update = true; + $widget_options['dashboard_secondary'] = array( + 'link' => apply_filters( 'dashboard_secondary_link', 'http://planet.wordpress.org/' ), + 'url' => apply_filters( 'dashboard_secondary_feed', 'http://planet.wordpress.org/feed/' ), + 'title' => apply_filters( 'dashboard_secondary_title', __( 'Other WordPress News' ) ), + 'items' => 15 + ); + } + wp_register_sidebar_widget( 'dashboard_secondary', $widget_options['dashboard_secondary']['title'], 'wp_dashboard_empty', + array( 'all_link' => $widget_options['dashboard_secondary']['link'], 'feed_link' => $widget_options['dashboard_secondary']['url'], 'width' => 'full' ), + 'wp_dashboard_cached_rss_widget', 'wp_dashboard_secondary_output' + ); + wp_register_widget_control( 'dashboard_secondary', __( 'Secondary Feed' ), 'wp_dashboard_rss_control', array(), + array( 'widget_id' => 'dashboard_secondary', 'form_inputs' => array( 'show_summary' => false, 'show_author' => false, 'show_date' => false ) ) + ); + + + /* Dashboard Widget Template + wp_register_sidebar_widget( $widget_id (unique slug) , $widget_title, $output_callback, + array( + 'all_link' => full url for "See All" link, + 'feed_link' => full url for "RSS" link, + 'width' => 'fourth', 'third', 'half', 'full' (defaults to 'half'), + 'height' => 'single', 'double' (defaults to 'single'), + ), + $wp_dashboard_empty_callback (only needed if using 'wp_dashboard_empty' as your $output_callback), + $arg, $arg, $arg... (further args passed to callbacks) + ); + + // optional: if you want users to be able to edit the settings of your widget, you need to register a widget_control + wp_register_widget_control( $widget_id, $widget_control_title, $control_output_callback, + array(), // leave an empty array here: oddity in widget code + array( + 'widget_id' => $widget_id, // Yes - again. This is required: oddity in widget code + 'arg' => an arg to pass to the $control_output_callback, + 'another' => another arg to pass to the $control_output_callback, + ... + ) + ); + */ + + // Hook to register new widgets + do_action( 'wp_dashboard_setup' ); + + // Hard code the sidebar's widgets and order + $dashboard_widgets = array(); + $dashboard_widgets[] = 'dashboard_recent_comments'; + $dashboard_widgets[] = 'dashboard_incoming_links'; + $dashboard_widgets[] = 'dashboard_primary'; + if ( current_user_can( 'activate_plugins' ) ) + $dashboard_widgets[] = 'dashboard_plugins'; + $dashboard_widgets[] = 'dashboard_secondary'; + + // Filter widget order + $dashboard_widgets = apply_filters( 'wp_dashboard_widgets', $dashboard_widgets ); + + $wp_dashboard_sidebars = array( 'wp_dashboard' => $dashboard_widgets, 'array_version' => 3.5 ); + + add_filter( 'dynamic_sidebar_params', 'wp_dashboard_dynamic_sidebar_params' ); + + if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget_id']) ) { + ob_start(); // hack - but the same hack wp-admin/widgets.php uses + wp_dashbaord_trigger_widget_control( $_POST['widget_id'] ); + ob_end_clean(); + wp_redirect( remove_query_arg( 'edit' ) ); + exit; + } + + if ( $update ) + update_option( 'dashboard_widget_options', $widget_options ); +} + +// Echoes out the dashboard +function wp_dashboard() { + echo "<div id='dashboard-widgets'>\n\n"; + + // We're already filtering dynamic_sidebar_params obove + add_filter( 'option_sidebars_widgets', 'wp_dashboard_sidebars_widgets' ); // here there be hackery + dynamic_sidebar( 'wp_dashboard' ); + remove_filter( 'option_sidebars_widgets', 'wp_dashboard_sidebars_widgets' ); + + echo "<br class='clear' />\n</div>\n\n\n"; +} + +// Makes sidebar_widgets option reflect the dashboard settings +function wp_dashboard_sidebars_widgets() { // hackery + return $GLOBALS['wp_dashboard_sidebars']; +} + +// Modifies sidbar params on the fly to set up ids, class names, titles for each widget (called once per widget) +// Switches widget to edit mode if $_GET['edit'] +function wp_dashboard_dynamic_sidebar_params( $params ) { + global $wp_registered_widgets, $wp_registered_widget_controls; + + $sidebar_defaults = array('widget_id' => 0, 'before_widget' => '', 'after_widget' => '', 'before_title' => '', 'after_title' => ''); + extract( $sidebar_defaults, EXTR_PREFIX_ALL, 'sidebar' ); + extract( $params[0], EXTR_PREFIX_ALL, 'sidebar' ); + + if ( !isset($wp_registered_widgets[$sidebar_widget_id]) || !is_array($wp_registered_widgets[$sidebar_widget_id]) ) { + return $params; + } + $widget_defaults = array('id' => '', 'width' => '', 'height' => '', 'class' => '', 'feed_link' => '', 'all_link' => '', 'notice' => false, 'error' => false); + extract( $widget_defaults, EXTR_PREFIX_ALL, 'widget' ); + extract( $wp_registered_widgets[$sidebar_widget_id], EXTR_PREFIX_ALL, 'widget' ); + + $the_classes = array(); + if ( in_array($widget_width, array( 'third', 'fourth', 'full' ) ) ) + $the_classes[] = $widget_width; + + if ( 'double' == $widget_height ) + $the_classes[] = 'double'; + + if ( $widget_class ) + $the_classes[] = $widget_class; + + // Add classes to the widget holder + if ( $the_classes ) + $sidebar_before_widget = str_replace( "<div class='dashboard-widget-holder ", "<div class='dashboard-widget-holder " . join( ' ', $the_classes ) . ' ', $sidebar_before_widget ); + + $links = array(); + if ( $widget_all_link ) + $links[] = '<a href="' . clean_url( $widget_all_link ) . '">' . __( 'See All' ) . '</a>'; + + $content_class = 'dashboard-widget-content'; + if ( current_user_can( 'edit_dashboard' ) && isset($wp_registered_widget_controls[$widget_id]) && is_callable($wp_registered_widget_controls[$widget_id]['callback']) ) { + // Switch this widget to edit mode + if ( isset($_GET['edit']) && $_GET['edit'] == $widget_id ) { + $content_class .= ' dashboard-widget-control'; + $wp_registered_widgets[$widget_id]['callback'] = 'wp_dashboard_empty'; + $sidebar_widget_name = $wp_registered_widget_controls[$widget_id]['name']; + $params[1] = 'wp_dashbaord_trigger_widget_control'; + $sidebar_before_widget .= '<form action="' . remove_query_arg( 'edit' ) . '" method="post">'; + $sidebar_after_widget = "<div class='dashboard-widget-submit'><input type='hidden' name='sidebar' value='wp_dashboard' /><input type='hidden' name='widget_id' value='$widget_id' /><input type='submit' value='" . __( 'Save' ) . "' /></div></form>$sidebar_after_widget"; + $links[] = '<a href="' . remove_query_arg( 'edit' ) . '">' . __( 'Cancel' ) . '</a>'; + } else { + $links[] = '<a href="' . add_query_arg( 'edit', $widget_id ) . "#$widget_id" . '">' . __( 'Edit' ) . '</a>'; + } + } + + if ( $widget_feed_link ) + $links[] = '<img class="rss-icon" src="' . get_option( 'siteurl' ) . '/' . WPINC . '/images/rss.png" alt="' . __( 'rss icon' ) . '" /> <a href="' . clean_url( $widget_feed_link ) . '">' . __( 'RSS' ) . '</a>'; + + $links = apply_filters( "wp_dashboard_widget_links_$widget_id", $links ); + + // Add links to widget's title bar + if ( $links ) { + $sidebar_before_title .= '<span>'; + $sidebar_after_title = '</span><small>' . join( ' | ', $links ) . "</small><br class='clear' />$sidebar_after_title"; + } + + // Could have put this in widget-content. Doesn't really matter + if ( $widget_notice ) + $sidebar_after_title .= "\t\t\t<div class='dashboard-widget-notice'>$widget_notice</div>\n\n"; + + if ( $widget_error ) + $sidebar_after_title .= "\t\t\t<div class='dashboard-widget-error'>$widget_error</div>\n\n"; + + $sidebar_after_title .= "\t\t\t<div class='$content_class'>\n\n"; + + $sidebar_after_widget .= "\t\t\t</div>\n\n"; + + foreach( array_keys( $params[0] ) as $key ) + $$key = ${'sidebar_' . $key}; + + $params[0] = compact( array_keys( $params[0] ) ); + + return $params; +} + + +/* Dashboard Widgets */ + +function wp_dashboard_recent_comments( $sidebar_args ) { + global $comment; + extract( $sidebar_args, EXTR_SKIP ); + + echo $before_widget; + + echo $before_title; + echo $widget_name; + echo $after_title; + + $lambda = create_function( '', 'return 5;' ); + add_filter( 'option_posts_per_rss', $lambda ); // hack - comments query doesn't accept per_page parameter + $comments_query = new WP_Query('feed=rss2&withcomments=1'); + remove_filter( 'option_posts_per_rss', $lambda ); + + $is_first = true; + + if ( $comments_query->have_comments() ) { + while ( $comments_query->have_comments() ) { $comments_query->the_comment(); + + $comment_post_url = get_permalink( $comment->comment_post_ID ); + $comment_post_title = get_the_title( $comment->comment_post_ID ); + $comment_post_link = "<a href='$comment_post_url'>$comment_post_title</a>"; + $comment_link = '<a class="comment-link" href="' . get_comment_link() . '">#</a>'; + $comment_meta = sprintf( __( 'From <strong>%1$s</strong> on %2$s %3$s' ), get_comment_author(), $comment_post_link, $comment_link ); + + if ( $is_first ) : $is_first = false; +?> + <blockquote><p>“<?php comment_excerpt(); ?>”</p></blockquote> + <p class='comment-meta'><?php echo $comment_meta; ?></p> + + <ul id="dashboard-comments-list"> +<?php + else : +?> + + <li class='comment-meta'><?php echo $comment_meta; ?></li> +<?php + endif; + } +?> + + </ul> + +<?php + + } + + echo $after_widget; +} + +// $sidebar_args are handled by wp_dashboard_empty() +function wp_dashboard_incoming_links_output() { + $widgets = get_option( 'dashboard_widget_options' ); + @extract( @$widgets['dashboard_incoming_links'], EXTR_SKIP ); + $rss = @fetch_rss( $url ); + if ( isset($rss->items) && 1 < count($rss->items) ) {// Technorati returns a 1-item feed when it has no results + + echo "<ul>\n"; + + $rss->items = array_slice($rss->items, 0, $items); + foreach ( $rss->items as $item ) { + $publisher = ''; + $site_link = ''; + $link = ''; + $content = ''; + $date = ''; + $link = clean_url( strip_tags( $item['link'] ) ); + + if ( isset( $item['author_uri'] ) ) + $site_link = clean_url( strip_tags( $item['author_uri'] ) ); + + if ( !$publisher = wp_specialchars( strip_tags( isset($item['dc']['publisher']) ? $item['dc']['publisher'] : $item['author_name'] ) ) ) + $publisher = __( 'Somebody' ); + if ( $site_link ) + $publisher = "<a href='$site_link'>$publisher</a>"; + else + $publisher = "<strong>$publisher</strong>"; + + if ( isset($item['description']) ) + $content = $item['description']; + elseif ( isset($item['summary']) ) + $content = $item['summary']; + elseif ( isset($item['atom_content']) ) + $content = $item['atom_content']; + else + $content = __( 'something' ); + $content = wp_html_excerpt($content, 50) . ' ...'; + if ( $link ) + $text = _c( '%1$s linked here <a href="%2$s">saying</a>, "%3$s"|feed_display' ); + else + $text = _c( '%1$s linked here saying, "%3$s"|feed_display' ); + + if ( $show_date ) { + if ( $show_author || $show_summary ) + $text .= _c( ' on %4$s|feed_display' ); + $date = wp_specialchars( strip_tags( isset($item['pubdate']) ? $item['pubdate'] : $item['published'] ) ); + $date = strtotime( $date ); + $date = gmdate( get_option( 'date_format' ), $date ); + } + + echo "\t<li>" . sprintf( _c( "$text|feed_display" ), $publisher, $link, $content, $date ) . "</li>\n"; + } + + echo "</ul>\n"; + + } else { + echo '<p>' . __('This dashboard widget queries <a href="http://blogsearch.google.com/">Google Blog Search</a> so that when another blog links to your site it will show up here. They have found no incoming links found… yet. It’s okay — there is no rush.') . "</p>\n"; + } +} + +// $sidebar_args are handled by wp_dashboard_empty() +function wp_dashboard_rss_output( $widget_id ) { + $widgets = get_option( 'dashboard_widget_options' ); + wp_widget_rss_output( $widgets[$widget_id] ); +} + +// $sidebar_args are handled by wp_dashboard_empty() +function wp_dashboard_secondary_output() { + $widgets = get_option( 'dashboard_widget_options' ); + @extract( @$widgets['dashboard_secondary'], EXTR_SKIP ); + $rss = @fetch_rss( $url ); + if ( !isset($rss->items) || 0 == count($rss->items) ) + return false; + + echo "<ul id='planetnews'>\n"; + + $rss->items = array_slice($rss->items, 0, $items); + foreach ($rss->items as $item ) { + $title = wp_specialchars($item['title']); + $author = preg_replace( '|(.+?):.+|s', '$1', $item['title'] ); + $post = preg_replace( '|.+?:(.+)|s', '$1', $item['title'] ); + $link = clean_url($item['link']); + + echo "\t<li><a href='$link'><span class='post'>$post</span><span class='hidden'> - </span><cite>$author</cite></a></li>\n"; + } + + echo "</ul>\n<br class='clear' />\n"; +} + +// $sidebar_args are handled by wp_dashboard_empty() +function wp_dashboard_plugins_output() { + $popular = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/popular/' ); + $new = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/new/' ); + $updated = @fetch_rss( 'http://wordpress.org/extend/plugins/rss/browse/updated/' ); + + foreach ( array( 'popular' => __('Most Popular'), 'new' => __('Newest Plugins'), 'updated' => __('Recently Updated') ) as $feed => $label ) { + if ( !isset($$feed->items) || 0 == count($$feed->items) ) + continue; + + $$feed->items = array_slice($$feed->items, 0, 5); + $item_key = array_rand($$feed->items); + + // Eliminate some common badly formed plugin descriptions + while ( ( null !== $item_key = array_rand($$feed->items) ) && false !== strpos( $$feed->items[$item_key]['description'], 'Plugin Name:' ) ) + unset($$feed->items[$item_key]); + + if ( !isset($$feed->items[$item_key]) ) + continue; + + $item = $$feed->items[$item_key]; + + // current bbPress feed item titles are: user on "topic title" + if ( preg_match( '/"(.*)"/s', $item['title'], $matches ) ) + $title = $matches[1]; + else // but let's make it forward compatible if things change + $title = $item['title']; + $title = wp_specialchars( $title ); + + $description = wp_specialchars( strip_tags(html_entity_decode($item['description'], ENT_QUOTES)) ); + + list($link, $frag) = explode( '#', $item['link'] ); + + $link = clean_url($link); + $dlink = rtrim($link, '/') . '/download/'; + + echo "<h4>$label</h4>\n"; + echo "<h5><a href='$link'>$title</a></h5> <span>(<a href='$dlink'>" . __( 'Download' ) . "</a>)</span>\n"; + echo "<p>$description</p>\n"; + } +} + +// Checks to see if all of the feed url in $check_urls are cached. +// If $check_urls is empty, look for the rss feed url found in the dashboard widget optios of $widget_id. +// If cached, call $callback, a function that echoes out output for this widget. +// If not cache, echo a "Loading..." stub which is later replaced by AJAX call (see top of /wp-admin/index.php) +function wp_dashboard_cached_rss_widget( $widget_id, $callback, $check_urls = array() ) { + $loading = '<p class="widget-loading">' . __( 'Loading…' ) . '</p>'; + + if ( empty($check_urls) ) { + $widgets = get_option( 'dashboard_widget_options' ); + if ( empty($widgets[$widget_id]['url']) ) { + echo $loading; + return false; + } + $check_urls = array( $widgets[$widget_id]['url'] ); + } + + + require_once( ABSPATH . WPINC . '/rss.php' ); + init(); // initialize rss constants + + $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE ); + + foreach ( $check_urls as $check_url ) { + $status = $cache->check_cache( $check_url ); + if ( 'HIT' !== $status ) { + echo $loading; + return false; + } + } + + if ( $callback && is_callable( $callback ) ) { + $args = array_slice( func_get_args(), 2 ); + array_unshift( $args, $widget_id ); + call_user_func_array( $callback, $args ); + } + + return true; +} + +// Empty widget used for JS/AJAX created output. +// Callback inserts content between before_widget and after_widget. Used when widget is in edit mode. Can also be used for custom widgets. +function wp_dashboard_empty( $sidebar_args, $callback = false ) { + extract( $sidebar_args, EXTR_SKIP ); + + echo $before_widget; + + echo $before_title; + echo $widget_name; + echo $after_title; + + // When in edit mode, the callback passed to this function is the widget_control callback + if ( $callback && is_callable( $callback ) ) { + $args = array_slice( func_get_args(), 2 ); + array_unshift( $args, $widget_id ); + call_user_func_array( $callback, $args ); + } + + echo $after_widget; +} + +/* Dashboard Widgets Controls. Ssee also wp_dashboard_empty() */ + +// Calls widget_control callback +function wp_dashbaord_trigger_widget_control( $widget_control_id = false ) { + global $wp_registered_widget_controls; + if ( is_scalar($widget_control_id) && $widget_control_id && isset($wp_registered_widget_controls[$widget_control_id]) && is_callable($wp_registered_widget_controls[$widget_control_id]['callback']) ) + call_user_func_array( $wp_registered_widget_controls[$widget_control_id]['callback'], $wp_registered_widget_controls[$widget_control_id]['params'] ); +} + +// Sets up $args to be used as input to wp_widget_rss_form(), handles POST data from RSS-type widgets +function wp_dashboard_rss_control( $args ) { + extract( $args ); + if ( !$widget_id ) + return false; + + if ( !$widget_options = get_option( 'dashboard_widget_options' ) ) + $widget_options = array(); + + if ( !isset($widget_options[$widget_id]) ) + $widget_options[$widget_id] = array(); + + $number = 1; // Hack to use wp_widget_rss_form() + $widget_options[$widget_id]['number'] = $number; + + if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST['widget-rss'][$number]) ) { + $_POST['widget-rss'][$number] = stripslashes_deep( $_POST['widget-rss'][$number] ); + $widget_options[$widget_id] = wp_widget_rss_process( $_POST['widget-rss'][$number] ); + // title is optional. If black, fill it if possible + if ( !$widget_options[$widget_id]['title'] && isset($_POST['widget-rss'][$number]['title']) ) { + require_once(ABSPATH . WPINC . '/rss.php'); + $rss = fetch_rss($widget_options[$widget_id]['url']); + $widget_options[$widget_id]['title'] = htmlentities(strip_tags($rss->channel['title'])); + } + update_option( 'dashboard_widget_options', $widget_options ); + } + + wp_widget_rss_form( $widget_options[$widget_id], $form_inputs ); +} + +?> diff --git a/wp-admin/includes/export.php b/wp-admin/includes/export.php new file mode 100644 index 0000000..a712177 --- /dev/null +++ b/wp-admin/includes/export.php @@ -0,0 +1,255 @@ +<?php + +// version number for the export format. bump this when something changes that might affect compatibility. +define('WXR_VERSION', '1.0'); + +function export_wp($author='') { +global $wpdb, $post_ids, $post; + +do_action('export_wp'); + +$filename = 'wordpress.' . date('Y-m-d') . '.xml'; + +header('Content-Description: File Transfer'); +header("Content-Disposition: attachment; filename=$filename"); +header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true); + +$where = ''; +if ( $author and $author != 'all' ) { + $author_id = (int) $author; + $where = " WHERE post_author = '$author_id' "; +} + +// grab a snapshot of post IDs, just in case it changes during the export +$post_ids = $wpdb->get_col("SELECT ID FROM $wpdb->posts $where ORDER BY post_date_gmt ASC"); + +$categories = (array) get_categories('get=all'); +$tags = (array) get_tags('get=all'); + +function wxr_missing_parents($categories) { + if ( !is_array($categories) || empty($categories) ) + return array(); + + foreach ( $categories as $category ) + $parents[$category->term_id] = $category->parent; + + $parents = array_unique(array_diff($parents, array_keys($parents))); + + if ( $zero = array_search('0', $parents) ) + unset($parents[$zero]); + + return $parents; +} + +while ( $parents = wxr_missing_parents($categories) ) { + $found_parents = get_categories("include=" . join(', ', $parents)); + if ( is_array($found_parents) && count($found_parents) ) + $categories = array_merge($categories, $found_parents); + else + break; +} + +// Put them in order to be inserted with no child going before its parent +$pass = 0; +$passes = 1000 + count($categories); +while ( ( $cat = array_shift($categories) ) && ++$pass < $passes ) { + if ( $cat->parent == 0 || isset($cats[$cat->parent]) ) { + $cats[$cat->term_id] = $cat; + } else { + $categories[] = $cat; + } +} +unset($categories); + +function wxr_cdata($str) { + if ( seems_utf8($str) == false ) + $str = utf8_encode($str); + + // $str = ent2ncr(wp_specialchars($str)); + + $str = "<![CDATA[$str" . ( ( substr($str, -1) == ']' ) ? ' ' : '') . "]]>"; + + return $str; +} + +function wxr_site_url() { + global $current_site; + + // mu: the base url + if ( isset($current_site->domain) ) { + return 'http://'.$current_site->domain.$current_site->path; + } + // wp: the blog url + else { + return get_bloginfo_rss('url'); + } +} + +function wxr_cat_name($c) { + if ( empty($c->name) ) + return; + + echo '<wp:cat_name>' . wxr_cdata($c->name) . '</wp:cat_name>'; +} + +function wxr_category_description($c) { + if ( empty($c->description) ) + return; + + echo '<wp:category_description>' . wxr_cdata($c->description) . '</wp:category_description>'; +} + +function wxr_tag_name($t) { + if ( empty($t->name) ) + return; + + echo '<wp:tag_name>' . wxr_cdata($t->name) . '</wp:tag_name>'; +} + +function wxr_tag_description($t) { + if ( empty($t->description) ) + return; + + echo '<wp:tag_description>' . wxr_cdata($t->description) . '</wp:tag_description>'; +} + +function wxr_post_taxonomy() { + $categories = get_the_category(); + $tags = get_the_tags(); + $the_list = ''; + $filter = 'rss'; + + if ( !empty($categories) ) foreach ( (array) $categories as $category ) { + $cat_name = sanitize_term_field('name', $category->name, $category->term_id, 'category', $filter); + // for backwards compatibility + $the_list .= "\n\t\t<category><![CDATA[$cat_name]]></category>\n"; + // forwards compatibility: use a unique identifier for each cat to avoid clashes + // http://trac.wordpress.org/ticket/5447 + $the_list .= "\n\t\t<category domain=\"category\" nicename=\"{$category->slug}\"><![CDATA[$cat_name]]></category>\n"; + } + + if ( !empty($tags) ) foreach ( (array) $tags as $tag ) { + $tag_name = sanitize_term_field('name', $tag->name, $tag->term_id, 'post_tag', $filter); + $the_list .= "\n\t\t<category domain=\"tag\"><![CDATA[$tag_name]]></category>\n"; + // forwards compatibility as above + $the_list .= "\n\t\t<category domain=\"tag\" nicename=\"{$tag->slug}\"><![CDATA[$tag_name]]></category>\n"; + } + + echo $the_list; +} + +echo '<?xml version="1.0" encoding="' . get_bloginfo('charset') . '"?' . ">\n"; + +?> +<!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your blog. --> +<!-- It contains information about your blog's posts, comments, and categories. --> +<!-- You may use this file to transfer that content from one site to another. --> +<!-- This file is not intended to serve as a complete backup of your blog. --> + +<!-- To import this information into a WordPress blog follow these steps. --> +<!-- 1. Log into that blog as an administrator. --> +<!-- 2. Go to Manage: Import in the blog's admin panels. --> +<!-- 3. Choose "WordPress" from the list. --> +<!-- 4. Upload this file using the form provided on that page. --> +<!-- 5. You will first be asked to map the authors in this export file to users --> +<!-- on the blog. For each author, you may choose to map to an --> +<!-- existing user on the blog or to create a new user --> +<!-- 6. WordPress will then import each of the posts, comments, and categories --> +<!-- contained in this file into your blog --> + +<?php the_generator('export');?> +<rss version="2.0" + xmlns:content="http://purl.org/rss/1.0/modules/content/" + xmlns:wfw="http://wellformedweb.org/CommentAPI/" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:wp="http://wordpress.org/export/<?php echo WXR_VERSION; ?>/" +> + +<channel> + <title><?php bloginfo_rss('name'); ?></title> + <link><?php bloginfo_rss('url') ?></link> + <description><?php bloginfo_rss("description") ?></description> + <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></pubDate> + <generator>http://wordpress.org/?v=<?php bloginfo_rss('version'); ?></generator> + <language><?php echo get_option('rss_language'); ?></language> + <wp:wxr_version><?php echo WXR_VERSION; ?></wp:wxr_version> + <wp:base_site_url><?php echo wxr_site_url(); ?></wp:base_site_url> + <wp:base_blog_url><?php bloginfo_rss('url'); ?></wp:base_blog_url> +<?php if ( $cats ) : foreach ( $cats as $c ) : ?> + <wp:category><wp:category_nicename><?php echo $c->slug; ?></wp:category_nicename><wp:category_parent><?php echo $c->parent ? $cats[$c->parent]->name : ''; ?></wp:category_parent><?php wxr_cat_name($c); ?><?php wxr_category_description($c); ?></wp:category> +<?php endforeach; endif; ?> +<?php if ( $tags ) : foreach ( $tags as $t ) : ?> + <wp:tag><wp:tag_slug><?php echo $t->slug; ?></wp:tag_slug><?php wxr_tag_name($t); ?><?php wxr_tag_description($t); ?></wp:tag> +<?php endforeach; endif; ?> + <?php do_action('rss2_head'); ?> + <?php if ($post_ids) { + global $wp_query; + $wp_query->in_the_loop = true; // Fake being in the loop. + // fetch 20 posts at a time rather than loading the entire table into memory + while ( $next_posts = array_splice($post_ids, 0, 20) ) { + $where = "WHERE ID IN (".join(',', $next_posts).")"; + $posts = $wpdb->get_results("SELECT * FROM $wpdb->posts $where ORDER BY post_date_gmt ASC"); + foreach ($posts as $post) { + setup_postdata($post); ?> +<item> +<title><?php echo apply_filters('the_title_rss', $post->post_title); ?></title> +<link><?php the_permalink_rss() ?></link> +<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate> +<dc:creator><?php the_author() ?></dc:creator> +<?php wxr_post_taxonomy() ?> + +<guid isPermaLink="false"><?php the_guid(); ?></guid> +<description></description> +<content:encoded><![CDATA[<?php echo apply_filters('the_content_export', $post->post_content); ?>]]></content:encoded> +<wp:post_id><?php echo $post->ID; ?></wp:post_id> +<wp:post_date><?php echo $post->post_date; ?></wp:post_date> +<wp:post_date_gmt><?php echo $post->post_date_gmt; ?></wp:post_date_gmt> +<wp:comment_status><?php echo $post->comment_status; ?></wp:comment_status> +<wp:ping_status><?php echo $post->ping_status; ?></wp:ping_status> +<wp:post_name><?php echo $post->post_name; ?></wp:post_name> +<wp:status><?php echo $post->post_status; ?></wp:status> +<wp:post_parent><?php echo $post->post_parent; ?></wp:post_parent> +<wp:menu_order><?php echo $post->menu_order; ?></wp:menu_order> +<wp:post_type><?php echo $post->post_type; ?></wp:post_type> +<wp:post_password><?php echo $post->post_password; ?></wp:post_password> +<?php +if ($post->post_type == 'attachment') { ?> +<wp:attachment_url><?php echo wp_get_attachment_url($post->ID); ?></wp:attachment_url> +<?php } ?> +<?php +$postmeta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = $post->ID"); +if ( $postmeta ) { +?> +<?php foreach( $postmeta as $meta ) { ?> +<wp:postmeta> +<wp:meta_key><?php echo $meta->meta_key; ?></wp:meta_key> +<wp:meta_value><?Php echo $meta->meta_value; ?></wp:meta_value> +</wp:postmeta> +<?php } ?> +<?php } ?> +<?php +$comments = $wpdb->get_results("SELECT * FROM $wpdb->comments WHERE comment_post_ID = $post->ID"); +if ( $comments ) { foreach ( $comments as $c ) { ?> +<wp:comment> +<wp:comment_id><?php echo $c->comment_ID; ?></wp:comment_id> +<wp:comment_author><?php echo wxr_cdata($c->comment_author); ?></wp:comment_author> +<wp:comment_author_email><?php echo $c->comment_author_email; ?></wp:comment_author_email> +<wp:comment_author_url><?php echo $c->comment_author_url; ?></wp:comment_author_url> +<wp:comment_author_IP><?php echo $c->comment_author_IP; ?></wp:comment_author_IP> +<wp:comment_date><?php echo $c->comment_date; ?></wp:comment_date> +<wp:comment_date_gmt><?php echo $c->comment_date_gmt; ?></wp:comment_date_gmt> +<wp:comment_content><?php echo $c->comment_content; ?></wp:comment_content> +<wp:comment_approved><?php echo $c->comment_approved; ?></wp:comment_approved> +<wp:comment_type><?php echo $c->comment_type; ?></wp:comment_type> +<wp:comment_parent><?php echo $c->comment_parent; ?></wp:comment_parent> +<wp:comment_user_id><?php echo $c->user_id; ?></wp:comment_user_id> +</wp:comment> +<?php } } ?> + </item> +<?php } } } ?> +</channel> +</rss> +<?php +} + +?>
\ No newline at end of file diff --git a/wp-admin/includes/media.php b/wp-admin/includes/media.php new file mode 100644 index 0000000..b43c2da --- /dev/null +++ b/wp-admin/includes/media.php @@ -0,0 +1,1225 @@ +<?php + +function media_upload_tabs() { + $_default_tabs = array( + 'type' => __('Choose File'), // handler action suffix => tab text + 'gallery' => __('Gallery'), + 'library' => __('Media Library'), + ); + + return apply_filters('media_upload_tabs', $_default_tabs); +} + +function update_gallery_tab($tabs) { + global $wpdb; + if ( !isset($_REQUEST['post_id']) ) { + unset($tabs['gallery']); + return $tabs; + } + if ( intval($_REQUEST['post_id']) ) + $attachments = intval($wpdb->get_var($wpdb->prepare("SELECT count(*) FROM $wpdb->posts WHERE post_type = 'attachment' AND post_parent = %d", $_REQUEST['post_id']))); + + $tabs['gallery'] = sprintf(__('Gallery (%s)'), "<span id='attachments-count'>$attachments</span>"); + + return $tabs; +} +add_filter('media_upload_tabs', 'update_gallery_tab'); + +function the_media_upload_tabs() { + $tabs = media_upload_tabs(); + + if ( !empty($tabs) ) { + echo "<ul id='sidemenu'>\n"; + if ( isset($_GET['tab']) && array_key_exists($_GET['tab'], $tabs) ) + $current = $_GET['tab']; + else { + $keys = array_keys($tabs); + $current = array_shift($keys); + } + foreach ( $tabs as $callback => $text ) { + $class = ''; + if ( $current == $callback ) + $class = " class='current'"; + $href = add_query_arg(array('tab'=>$callback, 's'=>false, 'paged'=>false, 'post_mime_type'=>false, 'm'=>false)); + $link = "<a href='$href'$class>$text</a>"; + echo "\t<li id='tab-$callback'>$link</li>\n"; + } + echo "</ul>\n"; + } +} + +function get_image_send_to_editor($id, $alt, $title, $align, $url='', $rel = false, $size='medium') { + + $html = get_image_tag($id, $alt, $title, $align, $rel, $size); + + $rel = $rel ? ' rel="attachment wp-att-'.attribute_escape($id).'"' : ''; + + if ( $url ) + $html = "<a href='".attribute_escape($url)."'$rel>$html</a>"; + + $html = apply_filters( 'image_send_to_editor', $html, $id, $alt, $title, $align, $url ); + + return $html; +} + +function media_send_to_editor($html) { + ?> +<script type="text/javascript"> +<!-- +top.send_to_editor('<?php echo addslashes($html); ?>'); +top.tb_remove(); +--> +</script> + <?php + exit; +} + +// this handles the file upload POST itself, creating the attachment post +function media_handle_upload($file_id, $post_id, $post_data = array()) { + $overrides = array('test_form'=>false); + $file = wp_handle_upload($_FILES[$file_id], $overrides); + + if ( isset($file['error']) ) + return new wp_error( 'upload_error', $file['error'] ); + + $url = $file['url']; + $type = $file['type']; + $file = $file['file']; + $title = preg_replace('/\.[^.]+$/', '', basename($file)); + $content = ''; + + // use image exif/iptc data for title and caption defaults if possible + if ( $image_meta = @wp_read_image_metadata($file) ) { + if ( trim($image_meta['title']) ) + $title = $image_meta['title']; + if ( trim($image_meta['caption']) ) + $content = $image_meta['caption']; + } + + // Construct the attachment array + $attachment = array_merge( array( + 'post_mime_type' => $type, + 'guid' => $url, + 'post_parent' => $post_id, + 'post_title' => $title, + 'post_content' => $content, + ), $post_data ); + + // Save the data + $id = wp_insert_attachment($attachment, $file, $post_parent); + if ( !is_wp_error($id) ) { + wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) ); + } + + return $id; + +} + + +// wrap iframe content (produced by $content_func) in a doctype, html head/body etc +// any additional function args will be passed to content_func +function wp_iframe($content_func /* ... */) { +?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" <?php do_action('admin_xml_ns'); ?> <?php language_attributes(); ?>> +<head> +<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php echo get_option('blog_charset'); ?>" /> +<title><?php bloginfo('name') ?> › <?php _e('Uploads'); ?> — WordPress</title> +<?php +wp_admin_css( 'css/global' ); +wp_admin_css(); +wp_admin_css( 'css/colors' ); +?> +<script type="text/javascript"> +//<![CDATA[ +function addLoadEvent(func) {if ( typeof wpOnload!='function'){wpOnload=func;}else{ var oldonload=wpOnload;wpOnload=function(){oldonload();func();}}} +//]]> +</script> +<?php +do_action('admin_print_scripts'); +do_action('admin_head'); +if ( is_string($content_func) ) + do_action( "admin_head_{$content_func}" ); +?> +</head> +<body<?php if ( isset($GLOBALS['body_id']) ) echo ' id="' . $GLOBALS['body_id'] . '"'; ?>> +<?php + $args = func_get_args(); + $args = array_slice($args, 1); + call_user_func_array($content_func, $args); +?> +</body> +</html> +<?php +} + +function media_buttons() { + global $post_ID, $temp_ID; + $uploading_iframe_ID = (int) (0 == $post_ID ? $temp_ID : $post_ID); + $context = apply_filters('media_buttons_context', __('Add media: %s')); + $media_upload_iframe_src = "media-upload.php?post_id=$uploading_iframe_ID"; + $media_title = __('Add Media'); + $image_upload_iframe_src = apply_filters('image_upload_iframe_src', "$media_upload_iframe_src&type=image"); + $image_title = __('Add an Image'); + $video_upload_iframe_src = apply_filters('video_upload_iframe_src', "$media_upload_iframe_src&type=video"); + $video_title = __('Add Video'); + $audio_upload_iframe_src = apply_filters('audio_upload_iframe_src', "$media_upload_iframe_src&type=audio"); + $audio_title = __('Add Audio'); + $out = <<<EOF + + <a href="{$image_upload_iframe_src}&TB_iframe=true&height=500&width=640" class="thickbox" title='$image_title'><img src='images/media-button-image.gif' alt='$image_title' /></a> + <a href="{$video_upload_iframe_src}&TB_iframe=true&height=500&width=640" class="thickbox" title='$video_title'><img src='images/media-button-video.gif' alt='$video_title' /></a> + <a href="{$audio_upload_iframe_src}&TB_iframe=true&height=500&width=640" class="thickbox" title='$audio_title'><img src='images/media-button-music.gif' alt='$audio_title' /></a> + <a href="{$media_upload_iframe_src}&TB_iframe=true&height=500&width=640" class="thickbox" title='$media_title'><img src='images/media-button-other.gif' alt='$media_title' /></a> + +EOF; + printf($context, $out); +} +add_action( 'media_buttons', 'media_buttons' ); + +function media_buttons_head() { +$siteurl = get_option('siteurl'); +echo "<style type='text/css' media='all'> + @import '{$siteurl}/wp-includes/js/thickbox/thickbox.css?1'; + div#TB_title { + background-color: #222222; + color: #cfcfcf; + } + div#TB_title a, div#TB_title a:visited { + color: #cfcfcf; + } +</style>\n"; +} + +add_action( 'admin_print_scripts', 'media_buttons_head' ); + +function media_admin_css() { + wp_admin_css('css/media'); +} + +add_action('media_upload_media', 'media_upload_handler'); + +function media_upload_form_handler() { + check_admin_referer('media-form'); + + // Insert media button was clicked + if ( !empty($_FILES) ) { + // Upload File button was clicked + + $id = media_handle_upload('async-upload', $_REQUEST['post_id']); + + if ( is_wp_error($id) ) { + $errors['upload_error'] = $id; + $id = false; + } + } + + if ( !empty($_POST['attachments']) ) foreach ( $_POST['attachments'] as $attachment_id => $attachment ) { + $post = $_post = get_post($attachment_id, ARRAY_A); + if ( isset($attachment['post_content']) ) + $post['post_content'] = $attachment['post_content']; + if ( isset($attachment['post_title']) ) + $post['post_title'] = $attachment['post_title']; + if ( isset($attachment['post_excerpt']) ) + $post['post_excerpt'] = $attachment['post_excerpt']; + + $post = apply_filters('attachment_fields_to_save', $post, $attachment); + + if ( isset($post['errors']) ) { + $errors[$attachment_id] = $post['errors']; + unset($post['errors']); + } + + if ( $post != $_post ) + wp_update_post($post); + + foreach ( get_attachment_taxonomies($post) as $t ) + if ( isset($attachment[$t]) ) + wp_set_object_terms($attachment_id, array_map('trim', preg_split('/,+/', $attachment[$t])), $t, false); + } + + if ( isset($_POST['insert-gallery']) ) + return media_send_to_editor('[gallery]'); + + if ( isset($_POST['send']) ) { + $keys = array_keys($_POST['send']); + $send_id = (int) array_shift($keys); + $attachment = $_POST['attachments'][$send_id]; + $html = $attachment['post_title']; + if ( !empty($attachment['url']) ) + $html = "<a href='{$attachment['url']}'>$html</a>"; + $html = apply_filters('media_send_to_editor', $html, $send_id, $attachment); + return media_send_to_editor($html); + } + + return $errors; +} + +function media_upload_image() { + if ( !empty($_FILES) ) { + // Upload File button was clicked + $id = media_handle_upload('async-upload', $_REQUEST['post_id']); + unset($_FILES); + if ( is_wp_error($id) ) { + $errors['upload_error'] = $id; + $id = false; + } + } + + if ( !empty($_POST['insertonlybutton']) ) { + $src = $_POST['insertonly']['src']; + if ( !strpos($src, '://') ) + $src = "http://$src"; + $alt = attribute_escape($_POST['insertonly']['alt']); + if ( isset($_POST['insertonly']['align']) ) { + $align = attribute_escape($_POST['insertonly']['align']); + $class = " class='align$align'"; + } + $html = "<img src='$src' alt='$alt'$class />"; + return media_send_to_editor($html); + } + + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + return wp_iframe( 'media_upload_type_form', 'image', $errors, $id ); +} + +function media_upload_audio() { + if ( !empty($_FILES) ) { + // Upload File button was clicked + $id = media_handle_upload('async-upload', $_REQUEST['post_id']); + unset($_FILES); + if ( is_wp_error($id) ) { + $errors['upload_error'] = $id; + $id = false; + } + } + + if ( !empty($_POST['insertonlybutton']) ) { + $href = $_POST['insertonly']['href']; + if ( !strpos($href, '://') ) + $href = "http://$href"; + $title = attribute_escape($_POST['insertonly']['title']); + $html = "<a href='$href' >$title</a>"; + return media_send_to_editor($html); + } + + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + return wp_iframe( 'media_upload_type_form', 'audio', $errors, $id ); +} + +function media_upload_video() { + if ( !empty($_FILES) ) { + // Upload File button was clicked + $id = media_handle_upload('async-upload', $_REQUEST['post_id']); + unset($_FILES); + if ( is_wp_error($id) ) { + $errors['upload_error'] = $id; + $id = false; + } + } + + if ( !empty($_POST['insertonlybutton']) ) { + $href = $_POST['insertonly']['href']; + if ( !strpos($href, '://') ) + $href = "http://$href"; + $title = attribute_escape($_POST['insertonly']['title']); + $html = "<a href='$href' >$title</a>"; + return media_send_to_editor($html); + } + + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + return wp_iframe( 'media_upload_type_form', 'video', $errors, $id ); +} + +function media_upload_file() { + if ( !empty($_FILES) ) { + // Upload File button was clicked + $id = media_handle_upload('async-upload', $_REQUEST['post_id']); + unset($_FILES); + if ( is_wp_error($id) ) { + $errors['upload_error'] = $id; + $id = false; + } + } + + if ( !empty($_POST['insertonlybutton']) ) { + $href = $_POST['insertonly']['href']; + if ( !strpos($href, '://') ) + $href = "http://$href"; + $title = attribute_escape($_POST['insertonly']['title']); + $html = "<a href='$href' >$title</a>"; + return media_send_to_editor($html); + } + + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + return wp_iframe( 'media_upload_type_form', 'file', $errors, $id ); +} + +function media_upload_gallery() { + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + return wp_iframe( 'media_upload_gallery_form', $errors ); +} + +function media_upload_library() { + if ( !empty($_POST) ) { + $return = media_upload_form_handler(); + + if ( is_string($return) ) + return $return; + if ( is_array($return) ) + $errors = $return; + } + + return wp_iframe( 'media_upload_library_form', $errors ); +} + +function get_attachment_taxonomies($attachment) { + if ( is_int( $attachment ) ) + $attachment = get_post($attachment); + else if ( is_array($attachment) ) + $attachment = (object) $attachment; + + if ( ! is_object($attachment) ) + return array(); + + $filename = basename($attachment->guid); + + $objects = array('attachment'); + + if ( false !== strpos($filename, '.') ) + $objects[] = 'attachment:' . substr($filename, strrpos($filename, '.') + 1); + if ( !empty($attachment->post_mime_type) ) { + $objects[] = 'attachment:' . $attachment->post_mime_type; + if ( false !== strpos($attachment->post_mime_type, '/') ) + foreach ( explode('/', $attachment->post_mime_type) as $token ) + if ( !empty($token) ) + $objects[] = "attachment:$token"; + } + + $taxonomies = array(); + foreach ( $objects as $object ) + if ( $taxes = get_object_taxonomies($object) ) + $taxonomies = array_merge($taxonomies, $taxes); + + return array_unique($taxonomies); +} + +function image_attachment_fields_to_edit($form_fields, $post) { + if ( substr($post->post_mime_type, 0, 5) == 'image' ) { + $form_fields['post_title']['required'] = true; + $form_fields['post_excerpt']['label'] = __('Description'); + $form_fields['post_excerpt']['helps'][] = __('Alternate text, e.g. "The Mona Lisa"'); + + $form_fields['post_content']['label'] = __('Long Description'); + + $thumb = wp_get_attachment_thumb_url($post->ID); + + $form_fields['align'] = array( + 'label' => __('Alignment'), + 'input' => 'html', + 'html' => " + <input type='radio' name='attachments[$post->ID][align]' id='image-align-none-$post->ID' value='none' /> + <label for='image-align-none-$post->ID' class='align image-align-none-label'>" . __('None') . "</label> + <input type='radio' name='attachments[$post->ID][align]' id='image-align-left-$post->ID' value='left' /> + <label for='image-align-left-$post->ID' class='align image-align-left-label'>" . __('Left') . "</label> + <input type='radio' name='attachments[$post->ID][align]' id='image-align-center-$post->ID' value='center' /> + <label for='image-align-center-$post->ID' class='align image-align-center-label'>" . __('Center') . "</label> + <input type='radio' name='attachments[$post->ID][align]' id='image-align-right-$post->ID' value='right' /> + <label for='image-align-right-$post->ID' class='align image-align-right-label'>" . __('Right') . "</label>\n", + ); + $form_fields['image-size'] = array( + 'label' => __('Size'), + 'input' => 'html', + 'html' => " + " . ( $thumb ? "<input type='radio' name='attachments[$post->ID][image-size]' id='image-size-thumb-$post->ID' value='thumbnail' /> + <label for='image-size-thumb-$post->ID'>" . __('Thumbnail') . "</label> + " : '' ) . "<input type='radio' name='attachments[$post->ID][image-size]' id='image-size-medium-$post->ID' value='medium' checked='checked' /> + <label for='image-size-medium-$post->ID'>" . __('Medium') . "</label> + <input type='radio' name='attachments[$post->ID][image-size]' id='image-size-full-$post->ID' value='full' /> + <label for='image-size-full-$post->ID'>" . __('Full size') . "</label>", + ); + } + return $form_fields; +} + +add_filter('attachment_fields_to_edit', 'image_attachment_fields_to_edit', 10, 2); + +function media_single_attachment_fields_to_edit( $form_fields, $post ) { + unset($form_fields['url'], $form_fields['align'], $form_fields['image-size']); + return $form_fields; +} + +function image_attachment_fields_to_save($post, $attachment) { + if ( substr($post['post_mime_type'], 0, 5) == 'image' ) { + if ( strlen(trim($post['post_title'])) == 0 ) { + $post['post_title'] = preg_replace('/\.\w+$/', '', basename($post['guid'])); + $post['errors']['post_title']['errors'][] = __('Empty Title filled from filename.'); + } + } + + return $post; +} + +add_filter('attachment_fields_to_save', 'image_attachment_fields_to_save', 10, 2); + +function image_media_send_to_editor($html, $attachment_id, $attachment) { + $post =& get_post($attachment_id); + if ( substr($post->post_mime_type, 0, 5) == 'image' ) { + $url = $attachment['url']; + + if ( isset($attachment['align']) ) + $align = $attachment['align']; + else + $align = 'none'; + + if ( !empty($attachment['image-size']) ) + $size = $attachment['image-size']; + else + $size = 'medium'; + + return get_image_send_to_editor($attachment_id, $attachment['post_excerpt'], $attachment['post_title'], $align, $url, $rel, $size); + } + + return $html; +} + +add_filter('media_send_to_editor', 'image_media_send_to_editor', 10, 3); + +function get_attachment_fields_to_edit($post, $errors = null) { + if ( is_int($post) ) + $post =& get_post($post); + if ( is_array($post) ) + $post = (object) $post; + + $edit_post = sanitize_post($post, 'edit'); + $file = wp_get_attachment_url($post->ID); + $link = get_attachment_link($post->ID); + + $form_fields = array( + 'post_title' => array( + 'label' => __('Title'), + 'value' => $edit_post->post_title, + ), + 'post_excerpt' => array( + 'label' => __('Description'), + 'value' => $edit_post->post_excerpt, + ), + 'post_content' => array( + 'label' => __('Long description'), + 'value' => $edit_post->post_content, + 'input' => 'textarea', + ), + 'url' => array( + 'label' => __('Link URL'), + 'input' => 'html', + 'html' => " + <input type='text' name='attachments[$post->ID][url]' value='" . attribute_escape($file) . "' /><br /> + <button type='button' class='button url-$post->ID' value=''>" . __('None') . "</button> + <button type='button' class='button url-$post->ID' value='" . attribute_escape($file) . "'>" . __('File URL') . "</button> + <button type='button' class='button url-$post->ID' value='" . attribute_escape($link) . "'>" . __('Post URL') . "</button> + <script type='text/javascript'> + jQuery('button.url-$post->ID').bind('click', function(){jQuery(this).siblings('input').val(this.value);}); + </script>\n", + 'helps' => __('Enter a link URL or click above for presets.'), + ), + ); + + foreach ( get_attachment_taxonomies($post) as $taxonomy ) { + $t = (array) get_taxonomy($taxonomy); + if ( empty($t['label']) ) + $t['label'] = $taxonomy; + if ( empty($t['args']) ) + $t['args'] = array(); + + $terms = get_object_term_cache($post->ID, $taxonomy); + if ( empty($terms) ) + $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']); + + $values = array(); + + foreach ( $terms as $term ) + $values[] = $term->name; + $t['value'] = join(', ', $values); + + $form_fields[$taxonomy] = $t; + } + + // Merge default fields with their errors, so any key passed with the error (e.g. 'error', 'helps', 'value') will replace the default + // The recursive merge is easily traversed with array casting: foreach( (array) $things as $thing ) + $form_fields = array_merge_recursive($form_fields, (array) $errors); + + $form_fields = apply_filters('attachment_fields_to_edit', $form_fields, $post); + + return $form_fields; +} + +function get_media_items( $post_id, $errors ) { + if ( $post_id && $post = get_post($post_id) ) { + if ( $post->post_type == 'attachment' ) + $attachments = array($post->ID => $post); + else + $attachments = get_children("post_parent=$post_id&post_type=attachment&orderby=menu_order ASC, ID&order=DESC"); + } else { + if ( is_array($GLOBALS['wp_the_query']->posts) ) + foreach ( $GLOBALS['wp_the_query']->posts as $attachment ) + $attachments[$attachment->ID] = $attachment; + } + + if ( empty($attachments) ) + return ''; + + foreach ( $attachments as $id => $attachment ) + if ( $item = get_media_item( $id, array( 'errors' => isset($errors[$id]) ? $errors[$id] : null) ) ) + $output .= "\n<div id='media-item-$id' class='media-item child-of-$attachment->post_parent preloaded'><div id='media-upload-error-$id'></div><div class='filename'></div><div class='progress'><div class='bar'></div></div>$item<div class='progress clickmask'></div>\n</div>"; + + return $output; +} + +function get_media_item( $attachment_id, $args = null ) { + $default_args = array( 'errors' => null, 'send' => true, 'delete' => true, 'toggle' => true ); + $args = wp_parse_args( $args, $default_args ); + extract( $args, EXTR_SKIP ); + + global $post_mime_types; + if ( ( $attachment_id = intval($attachment_id) ) && $thumb_url = get_attachment_icon_src( $attachment_id ) ) + $thumb_url = $thumb_url[0]; + else + return false; + + $title_label = __('Title'); + $description_label = __('Description'); + $tags_label = __('Tags'); + + $toggle_on = __('Show'); + $toggle_off = __('Hide'); + + $post = get_post($attachment_id); + + $filename = basename($post->guid); + $title = attribute_escape($post->post_title); + $description = attribute_escape($post->post_content); + if ( $_tags = get_the_tags($attachment_id) ) { + foreach ( $_tags as $tag ) + $tags[] = $tag->name; + $tags = attribute_escape(join(', ', $tags)); + } + + if ( isset($post_mime_types) ) { + $keys = array_keys(wp_match_mime_types(array_keys($post_mime_types), $post->post_mime_type)); + $type = array_shift($keys); + $type = "<input type='hidden' id='type-of-$attachment_id' value='$type' />"; + } + + $form_fields = get_attachment_fields_to_edit($post, $errors); + + if ( $toggle ) { + $class = empty($errors) ? 'startclosed' : 'startopen'; + $toggle_links = " + <a class='toggle describe-toggle-on' href='#'>$toggle_on</a> + <a class='toggle describe-toggle-off' href='#'>$toggle_off</a>"; + } else { + $class = 'form-table'; + $toggle_links = ''; + } + + $item = " + $type + $toggle_links + <div class='filename new'>$filename</div> + <table class='slidetoggle describe $class'> + <tbody class='media-item-info'> + <tr> + <td class='A1B1' rowspan='4'><img class='thumbnail' src='$thumb_url' alt='' /></td> + <td>$filename</td> + </tr> + <td>$post->post_mime_type</td></tr> + <tr><td>" . mysql2date($post->post_date, get_option('time_format')) . "</td></tr> + <tr><td>" . apply_filters('media_meta', '', $post) . "</tr></td> + </tbody> + <tbody>\n"; + + $defaults = array( + 'input' => 'text', + 'required' => false, + 'value' => '', + 'extra_rows' => array(), + ); + + $delete_href = wp_nonce_url("post.php?action=delete-post&post=$attachment_id", 'delete-post_' . $attachment_id); + if ( $send ) + $send = "<button type='submit' class='button' value='1' name='send[$attachment_id]'>" . __('Insert into Post') . '</button>'; + if ( $delete ) + $delete = "<a href='$delete_href' id='del[$attachment_id]' disabled='disabled' class='delete'>" . __('Delete') . "</button>"; + if ( ( $send || $delete ) && !isset($form_fields['buttons']) ) + $form_fields['buttons'] = array('tr' => "\t\t<tr class='submit'><td></td><td class='savesend'>$send $delete</td></tr>\n"); + + $hidden_fields = array(); + + foreach ( $form_fields as $id => $field ) { + if ( $id{0} == '_' ) + continue; + + if ( !empty($field['tr']) ) { + $item .= $field['tr']; + continue; + } + + $field = array_merge($defaults, $field); + $name = "attachments[$attachment_id][$id]"; + + if ( $field['input'] == 'hidden' ) { + $hidden_fields[$name] = $field['value']; + continue; + } + + $required = $field['required'] ? '<abbr title="required" class="required">*</abbr>' : ''; + $class = $id; + $class .= $field['required'] ? ' form-required' : ''; + + $item .= "\t\t<tr class='$class'>\n\t\t\t<th valign='top' scope='row' class='label'><label for='$name'><span class='alignleft'>{$field['label']}</span><span class='alignright'>$required</span><br class='clear' /></label></th>\n\t\t\t<td class='field'>"; + if ( !empty($field[$field['input']]) ) + $item .= $field[$field['input']]; + elseif ( $field['input'] == 'textarea' ) { + $item .= "<textarea type='text' id='$name' name='$name'>" . wp_specialchars($field['value'], 1) . "</textarea>"; + } else { + $item .= "<input type='text' id='$name' name='$name' value='" . wp_specialchars($field['value'], 1) . "' />"; + } + if ( !empty($field['helps']) ) + $item .= "<p class='help'>" . join( "</p>\n<p class='help'>", array_unique((array) $field['helps']) ) . '</p>'; + $item .= "</td>\n\t\t</tr>\n"; + + $extra_rows = array(); + + if ( !empty($field['errors']) ) + foreach ( array_unique((array) $field['errors']) as $error ) + $extra_rows['error'][] = $error; + + if ( !empty($field['extra_rows']) ) + foreach ( $field['extra_rows'] as $class => $rows ) + foreach ( (array) $rows as $html ) + $extra_rows[$class][] = $html; + + foreach ( $extra_rows as $class => $rows ) + foreach ( $rows as $html ) + $item .= "\t\t<tr><td></td><td class='$class'>$html</td></tr>\n"; + } + + if ( !empty($form_fields['_final']) ) + $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n"; + $item .= "\t</table>\n"; + + foreach ( $hidden_fields as $name => $value ) + $item .= "\t<input type='hidden' name='$name' id='$name' value='" . wp_specialchars($value, 1) . "' />\n"; + + return $item; +} + +function media_upload_header() { + ?> + <script type="text/javascript">post_id = <?php echo intval($_REQUEST['post_id']); ?>;</script> + <div id="media-upload-header"> + <?php the_media_upload_tabs(); ?> + </div> + <?php +} + +function media_upload_form( $errors = null ) { + global $type, $tab; + + $flash_action_url = get_option('siteurl') . "/wp-admin/async-upload.php"; + + $post_id = intval($_REQUEST['post_id']); + +?> +<input type='hidden' name='post_id' value='<?php echo $post_id; ?>' /> +<div id="media-upload-error"> +<?php if (isset($errors['upload_error']) && is_wp_error($errors['upload_error'])) { ?> + <?php echo $errors['upload_error']->get_error_message(); ?> +<?php } ?> +</div> +<script type="text/javascript"> +<!-- +jQuery(function($){ + swfu = new SWFUpload({ + upload_url : "<?php echo attribute_escape( $flash_action_url ); ?>", + flash_url : "<?php echo get_option('siteurl').'/wp-includes/js/swfupload/swfupload_f9.swf'; ?>", + file_post_name: "async-upload", + file_types: "*.*", + post_params : { + "post_id" : "<?php echo $post_id; ?>", + "auth_cookie" : "<?php echo $_COOKIE[AUTH_COOKIE]; ?>", + "type" : "<?php echo $type; ?>", + "tab" : "<?php echo $tab; ?>" + }, + file_size_limit : "<?php echo wp_max_upload_size(); ?>b", + swfupload_element_id : "flash-upload-ui", // id of the element displayed when swfupload is available + degraded_element_id : "html-upload-ui", // when swfupload is unavailable + swfupload_loaded_handler : uploadLoaded, + file_dialog_start_handler : fileDialogStart, + file_queued_handler : fileQueued, + upload_start_handler : uploadStart, + upload_progress_handler : uploadProgress, + upload_error_handler : uploadError, + upload_success_handler : uploadSuccess, + upload_complete_handler : uploadComplete, + file_queue_error_handler : fileQueueError, + file_dialog_complete_handler : fileDialogComplete, + + debug: false, + }); + $("#flash-browse-button").bind( "click", function(){swfu.selectFiles();}); +}); +//--> +</script> + + +<div id="flash-upload-ui"> + <p><input id="flash-browse-button" type="button" value="<?php _e('Choose files to upload'); ?>" class="button" /></p> + <p><?php _e('After a file has been uploaded, you can add titles and descriptions.'); ?></p> +</div> + +<div id="html-upload-ui"> + <p> + <input type="file" name="async-upload" id="async-upload" /> <input type="submit" class="button" value="<?php echo attribute_escape(__('Upload')); ?>" /> <a href="#" onClick="return top.tb_remove();"><?php _e('Cancel'); ?></a> + </p> + <input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" /> + <br style="clear:both" /> +</div> +<?php +} + +function media_upload_type_form($type = 'file', $errors = null, $id = null) { + media_upload_header(); + + $post_id = intval($_REQUEST['post_id']); + + $form_action_url = get_option('siteurl') . "/wp-admin/media-upload.php?type=$type&tab=type&post_id=$post_id"; + + $callback = "type_form_$type"; +?> + +<form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($form_action_url); ?>" class="media-upload-form type-form" id="<?php echo $type; ?>-form"> +<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" /> +<?php wp_nonce_field('media-form'); ?> +<h3><?php _e('From Computer'); ?></h3> +<?php media_upload_form( $errors ); ?> + +<script type="text/javascript"> +<!-- +jQuery(function($){ + var preloaded = $(".media-item.preloaded"); + if ( preloaded.length > 0 ) { + preloaded.each(function(){prepareMediaItem({id:this.id.replace(/[^0-9]/g, '')},'');}); + } + updateMediaForm(); +}); +--> +</script> +<?php if ( $id && !is_wp_error($id) ) : ?> +<div id="media-items"> +<?php echo get_media_items( $id, $errors ); ?> +</div> +<input type="submit" class="button savebutton" name="save" value="<?php _e('Save all changes'); ?>" /> + +<?php elseif ( is_callable($callback) ) : ?> + +<div class="media-blank"> +<p style="text-align:center"><?php _e('— OR —'); ?></p> +<h3><?php _e('From URL'); ?></h3> +</div> + +<div id="media-items"> +<div class="media-item media-blank"> +<?php echo call_user_func($callback); ?> +</div> +</div> +<input type="submit" class="button savebutton" name="save" value="<?php _e('Save all changes'); ?>" /> +<?php + endif; +} + +function media_upload_gallery_form($errors) { + media_upload_header(); + + $post_id = intval($_REQUEST['post_id']); + + $form_action_url = get_option('siteurl') . "/wp-admin/media-upload.php?type={$GLOBALS['type']}&tab=gallery&post_id=$post_id"; + +?> + +<script type="text/javascript"> +<!-- +jQuery(function($){ + var preloaded = $(".media-item.preloaded"); + if ( preloaded.length > 0 ) { + preloaded.each(function(){prepareMediaItem({id:this.id.replace(/[^0-9]/g, '')},'');}); + updateMediaForm(); + } +}); +--> +</script> + +<form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($form_action_url); ?>" class="media-upload-form" id="gallery-form"> +<?php wp_nonce_field('media-form'); ?> +<?php //media_upload_form( $errors ); ?> + +<div id="media-items"> +<?php echo get_media_items($post_id, $errors); ?> +</div> +<input type="submit" class="button savebutton" name="save" value="<?php _e('Save all changes'); ?>" /> +<input type="submit" class="button insert-gallery" name="insert-gallery" value="<?php _e('Insert gallery into post'); ?>" /> +<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" /> +<input type="hidden" name="type" value="<?php echo $GLOBALS['type']; ?>" /> +<input type="hidden" name="tab" value="<?php echo $GLOBALS['tab']; ?>" /> +</form> +<?php +} + +function media_upload_library_form($errors) { + global $wpdb, $wp_query, $wp_locale, $type, $tab, $post_mime_types; + + media_upload_header(); + + $post_id = intval($_REQUEST['post_id']); + + $form_action_url = get_option('siteurl') . "/wp-admin/media-upload.php?type={$GLOBALS['type']}&tab=library&post_id=$post_id"; + + $_GET['paged'] = intval($_GET['paged']); + if ( $_GET['paged'] < 1 ) + $_GET['paged'] = 1; + $start = ( $_GET['paged'] - 1 ) * 10; + if ( $start < 1 ) + $start = 0; + add_filter( 'post_limits', $limit_filter = create_function( '$a', "return 'LIMIT $start, 10';" ) ); + + list($post_mime_types, $avail_post_mime_types) = wp_edit_attachments_query(); + +?> + +<form id="filter" action="" method="get"> +<input type="hidden" name="type" value="<?php echo $type; ?>" /> +<input type="hidden" name="tab" value="<?php echo $tab; ?>" /> +<input type="hidden" name="post_id" value="<?php echo $post_id; ?>" /> +<input type="hidden" name="post_mime_type" value="<?php echo wp_specialchars($_GET['post_mime_type'], true); ?>" /> + +<div id="search-filter"> + <input type="text" id="post-search-input" name="s" value="<?php the_search_query(); ?>" /> + <input type="submit" value="<?php _e( 'Search Media' ); ?>" class="button" /> +</div> + +<p> +<ul class="subsubsub"> +<?php +$type_links = array(); +$_num_posts = (array) wp_count_attachments(); +$matches = wp_match_mime_types(array_keys($post_mime_types), array_keys($_num_posts)); +foreach ( $matches as $_type => $reals ) + foreach ( $reals as $real ) + $num_posts[$_type] += $_num_posts[$real]; +$class = empty($_GET['post_mime_type']) ? ' class="current"' : ''; +$type_links[] = "<li><a href='" . remove_query_arg(array('post_mime_type', 'paged', 'm')) . "'$class>".__('All Types')."</a>"; +foreach ( $post_mime_types as $mime_type => $label ) { + $class = ''; + + if ( !wp_match_mime_types($mime_type, $avail_post_mime_types) ) + continue; + + if ( wp_match_mime_types($mime_type, $_GET['post_mime_type']) ) + $class = ' class="current"'; + + $type_links[] = "<li><a href='" . add_query_arg(array('post_mime_type'=>$mime_type, 'paged'=>false)) . "'$class>" . sprintf($label[2], "<span id='$mime_type-counter'>{$num_posts[$mime_type]}</span>") . '</a>'; +} +echo implode(' | </li>', $type_links) . '</li>'; +unset($type_links); +?> +</ul> +</p> + +<div class="tablenav"> + +<?php +$page_links = paginate_links( array( + 'base' => add_query_arg( 'paged', '%#%' ), + 'format' => '', + 'total' => ceil($wp_query->found_posts / 10), + 'current' => $_GET['paged'] +)); + +if ( $page_links ) + echo "<div class='tablenav-pages'>$page_links</div>"; +?> + +<div style="float: left"> +<?php + +$arc_query = "SELECT DISTINCT YEAR(post_date) AS yyear, MONTH(post_date) AS mmonth FROM $wpdb->posts WHERE post_type = 'attachment' ORDER BY post_date DESC"; + +$arc_result = $wpdb->get_results( $arc_query ); + +$month_count = count($arc_result); + +if ( $month_count && !( 1 == $month_count && 0 == $arc_result[0]->mmonth ) ) { ?> +<select name='m'> +<option<?php selected( @$_GET['m'], 0 ); ?> value='0'><?php _e('Show all dates'); ?></option> +<?php +foreach ($arc_result as $arc_row) { + if ( $arc_row->yyear == 0 ) + continue; + $arc_row->mmonth = zeroise( $arc_row->mmonth, 2 ); + + if ( $arc_row->yyear . $arc_row->mmonth == $_GET['m'] ) + $default = ' selected="selected"'; + else + $default = ''; + + echo "<option$default value='$arc_row->yyear$arc_row->mmonth'>"; + echo $wp_locale->get_month($arc_row->mmonth) . " $arc_row->yyear"; + echo "</option>\n"; +} +?> +</select> +<?php } ?> + +<input type="submit" id="post-query-submit" value="<?php _e('Filter »'); ?>" class="button-secondary" /> + +</div> + +<br style="clear:both;" /> +</div> +</form> + +<form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($form_action_url); ?>" class="media-upload-form" id="library-form"> + +<?php wp_nonce_field('media-form'); ?> +<?php //media_upload_form( $errors ); ?> + +<script type="text/javascript"> +<!-- +jQuery(function($){ + var preloaded = $(".media-item.preloaded"); + if ( preloaded.length > 0 ) { + preloaded.each(function(){prepareMediaItem({id:this.id.replace(/[^0-9]/g, '')},'');}); + updateMediaForm(); + } +}); +--> +</script> + +<div id="media-items"> +<?php echo get_media_items(null, $errors); ?> +</div> +<input type="submit" class="button savebutton" name="save" value="<?php _e('Save all changes'); ?>" /> +<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" /> +</form> +<?php +} + +function type_form_image() { + return ' + <table class="describe"><tbody> + <tr> + <th valign="top" scope="row" class="label"> + <span class="alignleft"><label for="insertonly[src]">' . __('Image URL') . '</label></span> + <span class="alignright"><abbr title="required" class="required">*</abbr></span> + </th> + <td class="field"><input id="insertonly[src]" name="insertonly[src]" value="" type="text"></td> + </tr> + <tr> + <th valign="top" scope="row" class="label"> + <span class="alignleft"><label for="insertonly[alt]">' . __('Description') . '</label></span> + <span class="alignright"><abbr title="required">*</abbr></span> + </th> + <td class="field"><input id="insertonly[alt]" name="insertonly[alt]" value="" type="text"></td> + </tr> + <tr><td></td><td class="help">' . __('Alternate text, e.g. "The Mona Lisa"') . '</td></tr> + <tr class="align"> + <th valign="top" scope="row" class="label"><label for="insertonly[align]">' . __('Alignment') . '</label></th> + <td class="field"> + <input name="insertonly[align]" id="image-align-none-0" value="none" type="radio"> + <label for="image-align-none-0" class="align image-align-none-label">' . __('None') . '</label> + <input name="insertonly[align]" id="image-align-left-0" value="left" type="radio"> + <label for="image-align-left-0" class="align image-align-left-label">' . __('Left') . '</label> + <input name="insertonly[align]" id="image-align-center-0" value="center" type="radio"> + <label for="image-align-center-0" class="align image-align-center-label">' . __('Center') . '</label> + <input name="insertonly[align]" id="image-align-right-0" value="right" type="radio"> + <label for="image-align-right-0" class="align image-align-right-label">' . __('Right') . '</label> + </td> + </tr> + <tr> + <td></td> + <td> + <input type="submit" class="button" name="insertonlybutton" value="' . attribute_escape(__('Insert into Post')) . '" /> + </td> + </tr> + </tbody></table> +'; +} + +function type_form_audio() { + return ' + <table class="describe"><tbody> + <tr> + <th valign="top" scope="row" class="label"> + <span class="alignleft"><label for="insertonly[href]">' . __('Audio File URL') . '</label></span> + <span class="alignright"><abbr title="required" class="required">*</abbr></span> + </th> + <td class="field"><input id="insertonly[href]" name="insertonly[href]" value="" type="text"></td> + </tr> + <tr> + <th valign="top" scope="row" class="label"> + <span class="alignleft"><label for="insertonly[title]">' . __('Title') . '</label></span> + <span class="alignright"><abbr title="required" class="required">*</abbr></span> + </th> + <td class="field"><input id="insertonly[title]" name="insertonly[title]" value="" type="text"></td> + </tr> + <tr><td></td><td class="help">' . __('Link text, e.g. "Still Alive by Jonathan Coulton"') . '</td></tr> + <tr> + <td></td> + <td> + <input type="submit" class="button" name="insertonlybutton" value="' . attribute_escape(__('Insert into Post')) . '" /> + </td> + </tr> + </tbody></table> +'; +} + +function type_form_video() { + return ' + <table class="describe"><tbody> + <tr> + <th valign="top" scope="row" class="label"> + <span class="alignleft"><label for="insertonly[href]">' . __('Video URL') . '</label></span> + <span class="alignright"><abbr title="required" class="required">*</abbr></span> + </th> + <td class="field"><input id="insertonly[href]" name="insertonly[href]" value="" type="text"></td> + </tr> + <tr> + <th valign="top" scope="row" class="label"> + <span class="alignleft"><label for="insertonly[title]">' . __('Title') . '</label></span> + <span class="alignright"><abbr title="required" class="required">*</abbr></span> + </th> + <td class="field"><input id="insertonly[title]" name="insertonly[title]" value="" type="text"></td> + </tr> + <tr><td></td><td class="help">' . __('Link text, e.g. "Lucy on YouTube"') . '</td></tr> + <tr> + <td></td> + <td> + <input type="submit" class="button" name="insertonlybutton" value="' . attribute_escape(__('Insert into Post')) . '" /> + </td> + </tr> + </tbody></table> +'; +} + +function type_form_file() { + return ' + <table class="describe"><tbody> + <tr> + <th valign="top" scope="row" class="label"> + <span class="alignleft"><label for="insertonly[href]">' . __('URL') . '</label></span> + <span class="alignright"><abbr title="required" class="required">*</abbr></span> + </th> + <td class="field"><input id="insertonly[href]" name="insertonly[href]" value="" type="text"></td> + </tr> + <tr> + <th valign="top" scope="row" class="label"> + <span class="alignleft"><label for="insertonly[title]">' . __('Title') . '</label></span> + <span class="alignright"><abbr title="required" class="required">*</abbr></span> + </th> + <td class="field"><input id="insertonly[title]" name="insertonly[title]" value="" type="text"></td> + </tr> + <tr><td></td><td class="help">' . __('Link text, e.g. "Ransom Demands (PDF)"') . '</td></tr> + <tr> + <td></td> + <td> + <input type="submit" class="button" name="insertonlybutton" value="' . attribute_escape(__('Insert into Post')) . '" /> + </td> + </tr> + </tbody></table> +'; +} + +add_filter('async_upload_image', 'get_media_item', 10, 2); +add_filter('async_upload_audio', 'get_media_item', 10, 2); +add_filter('async_upload_video', 'get_media_item', 10, 2); +add_filter('async_upload_file', 'get_media_item', 10, 2); + +add_action('media_upload_image', 'media_upload_image'); +add_action('media_upload_audio', 'media_upload_audio'); +add_action('media_upload_video', 'media_upload_video'); +add_action('media_upload_file', 'media_upload_file'); +add_action('admin_head_media_upload_type_form', 'media_admin_css'); + +add_filter('media_upload_gallery', 'media_upload_gallery'); +add_action('admin_head_media_upload_gallery_form', 'media_admin_css'); + +add_filter('media_upload_library', 'media_upload_library'); +add_action('admin_head_media_upload_library_form', 'media_admin_css'); + + +// Any 'attachment' taxonomy will be included in the description input form for the multi uploader +// Example: +/* +register_taxonomy( + 'image_people', + 'attachment:image', + array( + 'label' => __('People'), + 'template' => __('People: %l'), + 'helps' => __('Left to right, top to bottom.'), + 'sort' => true, + 'args' => array( + 'orderby' => 'term_order' + ) + ) +); +*/ +/* +register_taxonomy('movie_director', 'attachment:video', array('label'=>__('Directors'), 'template'=>__('Directed by %l.'))); +register_taxonomy('movie_producer', 'attachment:video', array('label'=>__('Producers'), 'template'=>__('Produced by %l.'))); +register_taxonomy('movie_screenwriter', 'attachment:video', array('label'=>__('Screenwriter'), 'template'=>__('Screenplay by %l.'))); +register_taxonomy('movie_actor', 'attachment:video', array('label'=>__('Cast'), 'template'=>array(__('Cast: %l.'))); +register_taxonomy('movie_crew', 'attachment:video', array('label'=>__('Crew'), 'template'=>array(__('Crew: %l.'))); +*/ + +?> diff --git a/wp-admin/includes/widgets.php b/wp-admin/includes/widgets.php new file mode 100644 index 0000000..4523b24 --- /dev/null +++ b/wp-admin/includes/widgets.php @@ -0,0 +1,269 @@ +<?php + +// $_search is unsanitized +function wp_list_widgets( $show = 'all', $_search = false ) { + global $wp_registered_widgets, $sidebars_widgets; + if ( $_search ) { + // sanitize + $search = preg_replace( '/[^\w\s]/', '', $_search ); + // array of terms + $search_terms = preg_split( '/[\s]/', $search, -1, PREG_SPLIT_NO_EMPTY ); + } else { + $search_terms = array(); + } + + if ( !in_array( $show, array( 'all', 'unused', 'used' ) ) ) + $show = 'all'; +?> + + <ul id='widget-list'> + <?php + $no_widgets_shown = true; + $already_shown = array(); + foreach ( $wp_registered_widgets as $name => $widget ) : + if ( in_array( $widget['callback'], $already_shown ) ) // We already showed this multi-widget + continue; + + if ( $search_terms ) { + $hit = false; + // Simple case-insensitive search. Boolean OR. + $search_text = preg_replace( '/[^\w]/', '', $widget['name'] ); + if ( isset($widget['description']) ) + $search_text .= preg_replace( '/[^\w]/', '', $widget['description'] ); + + foreach ( $search_terms as $search_term ) { + if ( stristr( $search_text, $search_term ) ) { + $hit = true; + break; + } + } + if ( !$hit ) + continue; + } + + $sidebar = is_active_widget( $widget['callback'], $widget['id'] ); + + if ( ( 'unused' == $show && $sidebar ) || ( 'used' == $show && !$sidebar ) ) + continue; + + ob_start(); + $args = wp_list_widget_controls_dynamic_sidebar( array( 0 => array( 'widget_id' => $widget['id'], 'widget_name' => $widget['name'], '_display' => 'template' ) ) ); + $sidebar_args = call_user_func_array( 'wp_widget_control', $args ); + $widget_control_template = ob_get_contents(); + ob_end_clean(); + + $is_multi = false !== strpos( $widget_control_template, '%i%' ); + if ( !$sidebar || $is_multi ) { + if ( $is_multi ) + $already_shown[] = $widget['callback']; // it's a multi-widget. We only need to show it in the list once. + $action = 'add'; + $add_url = wp_nonce_url( add_query_arg( array( + 'sidebar' => $sidebar, + 'add' => $widget['id'], + 'key' => false, + 'edit' => false + ) ), "add-widget_$widget[id]" ); + } else { + $action = 'edit'; + $edit_url = clean_url( add_query_arg( array( + 'sidebar' => $sidebar, + 'edit' => $widget['id'], + 'key' => array_search( $widget['id'], $sidebars_widgets[$sidebar] ), + ) ) ); + + $widget_control_template = '<textarea rows="1" cols="1">' . htmlspecialchars( $widget_control_template ) . '</textarea>'; + } + + $widget_control_template = $sidebar_args['before_widget'] . $widget_control_template . $sidebar_args['after_widget']; + + $no_widgets_shown = false; + + ?> + + <li id="widget-list-item-<?php echo attribute_escape( $widget['id'] ); ?>" class="widget-list-item"> + <h4 class="widget-title widget-draggable"> + + <?php echo wp_specialchars( $widget['name'] ); ?> + + <?php if ( 'add' == $action ) : ?> + + <a class="widget-action widget-control-add" href="<?php echo $add_url; ?>"><?php _e( 'Add' ); ?></a> + + <?php elseif ( 'edit' == $action ) : + // We echo a hidden edit link for the sake of the JS. Edit links are shown (needlessly?) after a widget is added. + ?> + + <a class="widget-action widget-control-edit" href="<?php echo $edit_url; ?>" style="display: none;"><?php _e( 'Edit' ); ?></a> + + <?php endif; ?> + + </h4> + + + <ul id="widget-control-info-<?php echo $widget['id']; ?>" class="widget-control-info"> + + <?php echo $widget_control_template; ?> + + </ul> + + <?php if ( 'add' == $action ) : ?> + <?php endif; ?> + + <div class="widget-description"> + <?php echo ( $widget_description = wp_widget_description( $widget['id'] ) ) ? $widget_description : ' '; ?> + </div> + + <br class="clear" /> + + </li> + + <?php endforeach; if ( $no_widgets_shown ) : ?> + + <li><?php _e( 'No matching widgets' ); ?></li> + + <?php endif; ?> + + </ul> +<?php +} + + + +function wp_list_widget_controls( $sidebar ) { + add_filter( 'dynamic_sidebar_params', 'wp_list_widget_controls_dynamic_sidebar' ); +?> + + <ul class="widget-control-list"> + + <?php if ( !dynamic_sidebar( $sidebar ) ) echo "<li />"; ?> + + </ul> + +<?php +} + + +function wp_list_widget_controls_dynamic_sidebar( $params ) { + global $wp_registered_widgets; + static $i = 0; + $i++; + + $widget_id = $params[0]['widget_id']; + + $params[0]['before_widget'] = "<li id='widget-list-control-item-$i-$widget_id' class='widget-list-control-item widget-sortable'>\n"; + $params[0]['after_widget'] = "</li>"; + $params[0]['before_title'] = "%BEG_OF_TITLE%"; + $params[0]['after_title'] = "%END_OF_TITLE%"; + if ( is_callable( $wp_registered_widgets[$widget_id]['callback'] ) ) { + $wp_registered_widgets[$widget_id]['_callback'] = $wp_registered_widgets[$widget_id]['callback']; + $wp_registered_widgets[$widget_id]['callback'] = 'wp_widget_control'; + } + return $params; +} + +/* + * Meta widget used to display the control form for a widget. Called from dynamic_sidebar() + */ +function wp_widget_control( $sidebar_args ) { + global $wp_registered_widgets, $wp_registered_widget_controls, $sidebars_widgets, $edit_widget; + $widget_id = $sidebar_args['widget_id']; + $sidebar_id = isset($sidebar_args['id']) ? $sidebar_args['id'] : false; + + $control = $wp_registered_widget_controls[$widget_id]; + $widget = $wp_registered_widgets[$widget_id]; + + $key = $sidebar_id ? array_search( $widget_id, $sidebars_widgets[$sidebar_id] ) : 'no-key'; // position of widget in sidebar + + $edit = $edit_widget > 0 && $key && $edit_widget == $key; // (bool) are we currently editing this widget + + $id_format = $widget['id']; + // We aren't showing a widget control, we're outputing a template for a mult-widget control + if ( 'template' == $sidebar_args['_display'] && isset($control['params'][0]['number']) ) { + // number == -1 implies a template where id numbers are replaced by a generic '%i%' + $control['params'][0]['number'] = -1; + // if given, id_base means widget id's should be constructed like {$id_base}-{$id_number} + if ( isset($control['id_base']) ) + $id_format = $control['id_base'] . '-%i%'; + } + + $widget_title = ''; + // We grab the normal widget output to find the widget's title + if ( is_callable( $widget['_callback'] ) ) { + ob_start(); + $args = func_get_args(); + call_user_func_array( $widget['_callback'], $args ); + $widget_title = ob_get_clean(); + $widget_title = wp_widget_control_ob_filter( $widget_title ); + } + $wp_registered_widgets[$widget_id]['callback'] = $wp_registered_widgets[$widget_id]['_callback']; + unset($wp_registered_widgets[$widget_id]['_callback']); + + if ( $widget_title ) + $widget_title = sprintf( _c('%1$s: %2$s|widget_admin_title' ), $sidebar_args['widget_name'], $widget_title ); + else + $widget_title = wp_specialchars( strip_tags( $sidebar_args['widget_name'] ) ); + + + if ( empty($sidebar_args['_display']) || 'template' != $sidebar_args['_display'] ) + echo $sidebar_args['before_widget']; +?> + <h4 class="widget-title"><?php echo $widget_title ?> + + <?php if ( $edit ) : ?> + + <a class="widget-action widget-control-edit" href="<?php echo remove_query_arg( array( 'edit', 'key' ) ); ?>"><?php _e('Cancel'); ?></a> + + <?php else : ?> + + <a class="widget-action widget-control-edit" href="<?php echo clean_url( add_query_arg( array( 'edit' => $id_format, 'key' => $key ) ) ); ?>"><?php _e('Edit'); ?></a> + + <?php endif; ?> + + </h4> + + <div class="widget-control"<?php if ( $edit ) echo ' style="display: block;"'; ?>> + + <?php + if ( $control ) + call_user_func_array( $control['callback'], $control['params'] ); + else + echo '<p>' . __('There are no options for this widget.') . '</p>'; + ?> + + <input type="hidden" name="widget-id[]" value="<?php echo $id_format; ?>" /> + <input type="hidden" class="widget-width" value="<?php echo $control['width']; ?>" /> + + <div class="widget-control-actions"> + + <?php if ( $control ) : ?> + + <a class="widget-action widget-control-save wp-no-js-hidden edit alignleft" href="#save:<?php echo $id_format; ?>"><?php _e('Change'); ?></a> + + <?php endif; ?> + + <a class="widget-action widget-control-remove delete alignright" href="<?php echo clean_url( add_query_arg( array( 'remove' => $id_format, 'key' => $key ), wp_nonce_url( null, "remove-widget_$widget[id]" ) ) ); ?>"><?php _e('Remove'); ?></a> + <br class="clear" /> + </div> + </div> +<?php + if ( empty($sidebar_args['_display']) || 'template' != $sidebar_args['_display'] ) + echo $sidebar_args['after_widget']; + return $sidebar_args; +} + +function wp_widget_control_ob_filter( $string ) { + if ( false === $beg = strpos( $string, '%BEG_OF_TITLE%' ) ) + return ''; + if ( false === $end = strpos( $string, '%END_OF_TITLE%' ) ) + return ''; + $string = substr( $string, $beg + 14 , $end - $beg - 14); + return wp_specialchars( strip_tags( $string ) ); +} + +function widget_css() { + wp_admin_css( 'css/widgets' ); +} + +add_action( 'admin_head', 'widget_css' ); + +?> diff --git a/wp-admin/js/comment.js b/wp-admin/js/comment.js new file mode 100644 index 0000000..bde9b97 --- /dev/null +++ b/wp-admin/js/comment.js @@ -0,0 +1,12 @@ +addLoadEvent( function() { + add_postbox_toggles('comment'); + + jQuery('.edit-timestamp').click(function () { + if (jQuery('#timestampdiv').is(":hidden")) { + jQuery('#timestampdiv').slideDown("normal"); + } else { + jQuery('#timestampdiv').hide(); + } + return false; + }); +});
\ No newline at end of file diff --git a/wp-admin/js/common.js b/wp-admin/js/common.js new file mode 100644 index 0000000..9f05e55 --- /dev/null +++ b/wp-admin/js/common.js @@ -0,0 +1,12 @@ +addLoadEvent( function() { + // pulse + jQuery('.fade').animate( { backgroundColor: '#ffffe0' }, 300).animate( { backgroundColor: '#fffbcc' }, 300).animate( { backgroundColor: '#ffffe0' }, 300).animate( { backgroundColor: '#fffbcc' }, 300); + + // Reveal + jQuery('.wp-no-js-hidden').removeClass( 'wp-no-js-hidden' ); + + // Basic form validation + if ( ( 'undefined' != typeof wpAjax ) && jQuery.isFunction( wpAjax.validateForm ) ) { + jQuery('form').submit( function() { return wpAjax.validateForm( jQuery(this) ); } ); + } +}); diff --git a/wp-admin/js/dbx-admin-key.js b/wp-admin/js/dbx-admin-key.js deleted file mode 100644 index 3b3f7af..0000000 --- a/wp-admin/js/dbx-admin-key.js +++ /dev/null @@ -1,47 +0,0 @@ -addLoadEvent( function() {var manager = new dbxManager( dbxL10n.manager );} ); - -addLoadEvent( function() -{ - //create new docking boxes group - var meta = new dbxGroup( - 'grabit', // container ID [/-_a-zA-Z0-9/] - 'vertical', // orientation ['vertical'|'horizontal'] - '10', // drag threshold ['n' pixels] - 'no', // restrict drag movement to container axis ['yes'|'no'] - '10', // animate re-ordering [frames per transition, or '0' for no effect] - 'yes', // include open/close toggle buttons ['yes'|'no'] - 'closed', // default state ['open'|'closed'] - dbxL10n.open, // word for "open", as in "open this box" - dbxL10n.close, // word for "close", as in "close this box" - dbxL10n.moveMouse, // sentence for "move this box" by mouse - dbxL10n.toggleMouse, // pattern-match sentence for "(open|close) this box" by mouse - dbxL10n.moveKey, // sentence for "move this box" by keyboard - dbxL10n.toggleKey, // pattern-match sentence-fragment for "(open|close) this box" by keyboard - '%mytitle% [%dbxtitle%]' // pattern-match syntax for title-attribute conflicts - ); - - // Boxes are closed by default. Open the Category box if the cookie isn't already set. - var catdiv = document.getElementById('categorydiv'); - if ( catdiv ) { - var button = catdiv.getElementsByTagName('A')[0]; - if ( dbx.cookiestate == null && /dbx\-toggle\-closed/.test(button.className) ) - meta.toggleBoxState(button, true); - } - - var advanced = new dbxGroup( - 'advancedstuff', - 'vertical', - '10', - 'yes', // restrict drag movement to container axis ['yes'|'no'] - '10', - 'yes', - 'closed', - dbxL10n.open, - dbxL10n.close, - dbxL10n.moveMouse, - dbxL10n.toggleMouse, - dbxL10n.moveKey, - dbxL10n.toggleKey, - '%mytitle% [%dbxtitle%]' // pattern-match syntax for title-attribute conflicts - ); -}); diff --git a/wp-admin/js/editor.js b/wp-admin/js/editor.js new file mode 100644 index 0000000..a5500ec --- /dev/null +++ b/wp-admin/js/editor.js @@ -0,0 +1,153 @@ +wpEditorInit = function() { + // Activate tinyMCE if it's the user's default editor + if ( ( 'undefined' == typeof wpTinyMCEConfig ) || 'tinymce' == wpTinyMCEConfig.defaultEditor ) { + document.getElementById('editorcontainer').style.padding = '0px'; + tinyMCE.execCommand("mceAddControl", false, "content"); + } else { + var H; + if ( H = tinymce.util.Cookie.getHash("TinyMCE_content_size") ) + document.getElementById('content').style.height = H.ch - 30 + 'px'; + } +}; + +switchEditors = { + + saveCallback : function(el, content, body) { + + document.getElementById(el).style.color = '#fff'; + if ( tinyMCE.activeEditor.isHidden() ) + content = document.getElementById(el).value; + else + content = this.pre_wpautop(content); + + return content; + }, + + pre_wpautop : function(content) { + // We have a TON of cleanup to do. + + // Remove anonymous, empty paragraphs. + content = content.replace(new RegExp('<p>(\\s| |<br />)*</p>', 'mg'), ''); + + // Mark </p> if it has any attributes. + content = content.replace(new RegExp('(<p[^>]+>.*?)</p>', 'mg'), '$1</p#>'); + + // Get it ready for wpautop. + content = content.replace(new RegExp('\\s*<p>', 'mgi'), ''); + content = content.replace(new RegExp('\\s*</p>\\s*', 'mgi'), '\n\n'); + content = content.replace(new RegExp('\\n\\s*\\n', 'mgi'), '\n\n'); + content = content.replace(new RegExp('\\s*<br ?/?>\\s*', 'gi'), '\n'); + + // Fix some block element newline issues + var blocklist = 'blockquote|ul|ol|li|table|thead|tr|th|td|div|h\\d|pre'; + content = content.replace(new RegExp('\\s*<(('+blocklist+') ?[^>]*)\\s*>', 'mg'), '\n<$1>'); + content = content.replace(new RegExp('\\s*</('+blocklist+')>\\s*', 'mg'), '</$1>\n'); + content = content.replace(new RegExp('<li>', 'g'), '\t<li>'); + + if ( content.indexOf('<object') != -1 ) { + content = content.replace(new RegExp('\\s*<param([^>]*)>\\s*', 'g'), "<param$1>"); // no pee inside object/embed + content = content.replace(new RegExp('\\s*</embed>\\s*', 'g'), '</embed>'); + } + + // Unmark special paragraph closing tags + content = content.replace(new RegExp('</p#>', 'g'), '</p>\n'); + content = content.replace(new RegExp('\\s*(<p[^>]+>.*</p>)', 'mg'), '\n$1'); + + // Trim trailing whitespace + content = content.replace(new RegExp('\\s*$', ''), ''); + + // Hope. + return content; + }, + + go : function(id) { + var ed = tinyMCE.get(id); + var qt = document.getElementById('quicktags'); + var H = document.getElementById('edButtonHTML'); + var P = document.getElementById('edButtonPreview'); + var ta = document.getElementById(id); + var ec = document.getElementById('editorcontainer'); + + if ( ! ed || ed.isHidden() ) { + ta.style.color = '#fff'; + + this.edToggle(P, H); + edCloseAllTags(); // :-( + + qt.style.display = 'none'; + ec.style.padding = '0px'; + ta.style.padding = '0px'; + + ta.value = this.wpautop(ta.value); + + if ( ed ) ed.show(); + else tinyMCE.execCommand("mceAddControl", false, id); + + this.wpSetDefaultEditor('tinymce'); + } else { + this.edToggle(H, P); + ta.style.height = ed.getContentAreaContainer().offsetHeight + 6 + 'px'; + + ed.hide(); + qt.style.display = 'block'; + + if ( tinymce.isIE6 ) { + ta.style.width = '98%'; + ec.style.padding = '0px'; + ta.style.padding = '6px'; + } else { + ta.style.width = '100%'; + ec.style.padding = '6px'; + } + + ta.style.color = ''; + this.wpSetDefaultEditor('html'); + } + }, + + edToggle : function(A, B) { + A.className = 'active'; + B.className = ''; + + B.onclick = A.onclick; + A.onclick = null; + }, + + wpSetDefaultEditor : function(editor) { + try { + editor = escape( editor.toString() ); + } catch(err) { + editor = 'tinymce'; + } + + var userID = document.getElementById('user-id'); + var date = new Date(); + date.setTime(date.getTime()+(10*365*24*60*60*1000)); + document.cookie = "wordpress_editor_" + userID.value + "=" + editor + "; expires=" + date.toGMTString(); + }, + + wpautop : function(pee) { + var blocklist = 'table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|p|h[1-6]'; + + pee = pee + "\n\n"; + pee = pee.replace(new RegExp('<br />\\s*<br />', 'gi'), "\n\n"); + pee = pee.replace(new RegExp('(<(?:'+blocklist+')[^>]*>)', 'gi'), "\n$1"); + pee = pee.replace(new RegExp('(</(?:'+blocklist+')>)', 'gi'), "$1\n\n"); + pee = pee.replace(new RegExp("\\r\\n|\\r", 'g'), "\n"); + pee = pee.replace(new RegExp("\\n\\s*\\n+", 'g'), "\n\n"); + pee = pee.replace(new RegExp('([\\s\\S]+?)\\n\\n', 'mg'), "<p>$1</p>\n"); + pee = pee.replace(new RegExp('<p>\\s*?</p>', 'gi'), ''); + pee = pee.replace(new RegExp('<p>\\s*(</?(?:'+blocklist+')[^>]*>)\\s*</p>', 'gi'), "$1"); + pee = pee.replace(new RegExp("<p>(<li.+?)</p>", 'gi'), "$1"); + pee = pee.replace(new RegExp('<p><blockquote([^>]*)>', 'gi'), "<blockquote$1><p>"); + pee = pee.replace(new RegExp('</blockquote></p>', 'gi'), '</p></blockquote>'); + pee = pee.replace(new RegExp('<p>\\s*(</?(?:'+blocklist+')[^>]*>)', 'gi'), "$1"); + pee = pee.replace(new RegExp('(</?(?:'+blocklist+')[^>]*>)\\s*</p>', 'gi'), "$1"); + pee = pee.replace(new RegExp('\\s*\\n', 'gi'), "<br />\n"); + pee = pee.replace(new RegExp('(</?(?:'+blocklist+')[^>]*>)\\s*<br />', 'gi'), "$1"); + pee = pee.replace(new RegExp('<br />(\\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)', 'gi'), '$1'); + pee = pee.replace(new RegExp('^((?: )*)\\s', 'mg'), '$1 '); + //pee = pee.replace(new RegExp('(<pre.*?>)(.*?)</pre>!ise', " stripslashes('$1') . stripslashes(clean_pre('$2')) . '</pre>' "); // Hmm... + return pee; + } +} diff --git a/wp-admin/js/forms.js b/wp-admin/js/forms.js new file mode 100644 index 0000000..21a62f4 --- /dev/null +++ b/wp-admin/js/forms.js @@ -0,0 +1,31 @@ +function checkAll(form) { + for (i = 0, n = form.elements.length; i < n; i++) { + if(form.elements[i].type == "checkbox" && !(form.elements[i].hasAttribute('onclick'))) { + if(form.elements[i].checked == true) + form.elements[i].checked = false; + else + form.elements[i].checked = true; + } + } +} + +function getNumChecked(form) { + var num = 0; + for (i = 0, n = form.elements.length; i < n; i++) { + if (form.elements[i].type == "checkbox") { + if (form.elements[i].checked == true) + num++; + } + } + return num; +} + +function checkAllUsers(role) { + var checkboxs = document.getElementsByTagName('input'); + for(var i = 0, inp; inp = checkboxs[i]; i++) + if(inp.type.toLowerCase() == 'checkbox' && inp.className == role) + if(inp.checked == false) + inp.checked = true; + else + inp.checked = false; +}
\ No newline at end of file diff --git a/wp-admin/js/link-cat.js b/wp-admin/js/link-cat.js deleted file mode 100644 index a0775ce..0000000 --- a/wp-admin/js/link-cat.js +++ /dev/null @@ -1,10 +0,0 @@ -addLoadEvent(function(){linkcatList=new listMan('linkcategorychecklist');linkcatList.ajaxRespEl='jaxcat';linkcatList.topAdder=1;linkcatList.alt=0;linkcatList.showLink=0;}); -addLoadEvent(newLinkCatAddIn); -function newLinkCatAddIn() { - var jaxcat = $('jaxcat'); - if ( !jaxcat ) - return false; - Element.update(jaxcat,'<span id="ajaxcat"><input type="text" name="newcat" id="newcat" size="16" autocomplete="off"/><input type="button" name="Button" id="catadd" value="' + linkcatL10n.add + '"/><input type="hidden"/><span id="howto">' + linkcatL10n.how + '</span></span>'); - $('newcat').onkeypress = function(e) { return killSubmit("linkcatList.ajaxAdder('link-category','jaxcat');", e); }; - $('catadd').onclick = function() { linkcatList.ajaxAdder('link-category', 'jaxcat'); }; -} diff --git a/wp-admin/js/link.js b/wp-admin/js/link.js new file mode 100644 index 0000000..9f5a28d --- /dev/null +++ b/wp-admin/js/link.js @@ -0,0 +1,48 @@ +addLoadEvent( function() { + jQuery('#link_name').focus(); + // postboxes + add_postbox_toggles('link'); + + // category tabs + var categoryTabs = jQuery('#category-tabs').tabs(); + + // Ajax Cat + var newCat = jQuery('#newcat').one( 'focus', function() { jQuery(this).val( '' ).removeClass( 'form-input-tip' ) } ); + jQuery('#category-add-sumbit').click( function() { newCat.focus(); } ); + var noSyncChecks = false; // prophylactic. necessary? + var syncChecks = function() { + if ( noSyncChecks ) + return; + noSyncChecks = true; + var th = jQuery(this); + var c = th.is(':checked'); + var id = th.val().toString(); + jQuery('#in-category-' + id + ', #in-popular-category-' + id).attr( 'checked', c ); + noSyncChecks = false; + }; + var catAddAfter = function( r, s ) { + jQuery(s.what + ' response_data', r).each( function() { + var t = jQuery(jQuery(this).text()); + t.find( 'label' ).each( function() { + var th = jQuery(this); + var val = th.find('input').val(); + var id = th.find('input')[0].id + jQuery('#' + id).change( syncChecks ); + var name = jQuery.trim( th.text() ); + var o = jQuery( '<option value="' + parseInt( val, 10 ) + '"></option>' ).text( name ); + } ); + } ); + }; + jQuery('#categorychecklist').wpList( { + alt: '', + what: 'link-category', + response: 'category-ajax-response', + addAfter: catAddAfter + } ); + jQuery('#category-add-toggle').click( function() { + jQuery(this).parents('div:first').toggleClass( 'wp-hidden-children' ); + categoryTabs.tabsClick( 1 ); + return false; + } ); + jQuery('.categorychecklist :checkbox').change( syncChecks ).filter( ':checked' ).change(); +}); diff --git a/wp-admin/js/media-upload.js b/wp-admin/js/media-upload.js new file mode 100644 index 0000000..b8c615d --- /dev/null +++ b/wp-admin/js/media-upload.js @@ -0,0 +1,12 @@ +// send html to the post editor +function send_to_editor(h) { + var win = window.opener ? window.opener : window.dialogArguments; + if ( !win ) + win = top; + tinyMCE = win.tinyMCE; + if ( typeof tinyMCE != 'undefined' && ( ed = tinyMCE.getInstanceById('content') ) && !ed.isHidden() ) { + tinyMCE.selectedInstance.getWin().focus(); + tinyMCE.execCommand('mceInsertContent', false, h); + } else + win.edInsertContent(win.edCanvas, h); +}
\ No newline at end of file diff --git a/wp-admin/js/page.js b/wp-admin/js/page.js new file mode 100644 index 0000000..02fd708 --- /dev/null +++ b/wp-admin/js/page.js @@ -0,0 +1,16 @@ +addLoadEvent( function() { + add_postbox_toggles('page'); + make_slugedit_clickable(); + + // hide advanced slug field + jQuery('#pageslugdiv').hide(); + + jQuery('.edit-timestamp').click(function () { + if (jQuery('#timestampdiv').is(":hidden")) { + jQuery('#timestampdiv').slideDown("normal"); + } else { + jQuery('#timestampdiv').hide(); + } + return false; + }); +});
\ No newline at end of file diff --git a/wp-admin/js/password-strength-meter.js b/wp-admin/js/password-strength-meter.js new file mode 100644 index 0000000..eba43fc --- /dev/null +++ b/wp-admin/js/password-strength-meter.js @@ -0,0 +1,162 @@ +// Password strength meter +// This jQuery plugin is written by firas kassem [2007.04.05] +// Firas Kassem phiras.wordpress.com || phiras at gmail {dot} com +// for more information : http://phiras.wordpress.com/2007/04/08/password-strength-meter-a-jquery-plugin/ + +var shortPass = 'Too short' +var badPass = 'Bad' +var goodPass = 'Good' +var strongPass = 'Strong' + + + +function passwordStrength(password,username) +{ + score = 0 + + //password < 4 + if (password.length < 4 ) { return shortPass } + + //password == username + if (password.toLowerCase()==username.toLowerCase()) return badPass + + //password length + score += password.length * 4 + score += ( checkRepetition(1,password).length - password.length ) * 1 + score += ( checkRepetition(2,password).length - password.length ) * 1 + score += ( checkRepetition(3,password).length - password.length ) * 1 + score += ( checkRepetition(4,password).length - password.length ) * 1 + + //password has 3 numbers + if (password.match(/(.*[0-9].*[0-9].*[0-9])/)) score += 5 + + //password has 2 sybols + if (password.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/)) score += 5 + + //password has Upper and Lower chars + if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) score += 10 + + //password has number and chars + if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/)) score += 15 + // + //password has number and symbol + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([0-9])/)) score += 15 + + //password has char and symbol + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([a-zA-Z])/)) score += 15 + + //password is just a nubers or chars + if (password.match(/^\w+$/) || password.match(/^\d+$/) ) score -= 10 + + //verifing 0 < score < 100 + if ( score < 0 ) score = 0 + if ( score > 100 ) score = 100 + + if (score < 34 ) return badPass + if (score < 68 ) return goodPass + return strongPass +} + + +// checkRepetition(1,'aaaaaaabcbc') = 'abcbc' +// checkRepetition(2,'aaaaaaabcbc') = 'aabc' +// checkRepetition(2,'aaaaaaabcdbcd') = 'aabcd' + +function checkRepetition(pLen,str) { + res = "" + for ( i=0; i<str.length ; i++ ) { + repeated=true + for (j=0;j < pLen && (j+i+pLen) < str.length;j++) + repeated=repeated && (str.charAt(j+i)==str.charAt(j+i+pLen)) + if (j<pLen) repeated=false + if (repeated) { + i+=pLen-1 + repeated=false + } + else { + res+=str.charAt(i) + } + } + return res +} +// Password strength meter +// This jQuery plugin is written by firas kassem [2007.04.05] +// Firas Kassem phiras.wordpress.com || phiras at gmail {dot} com +// for more information : http://phiras.wordpress.com/2007/04/08/password-strength-meter-a-jquery-plugin/ + +var shortPass = 'Too short' +var badPass = 'Bad' +var goodPass = 'Good' +var strongPass = 'Strong' + + + +function passwordStrength(password,username) +{ + score = 0 + + //password < 4 + if (password.length < 4 ) { return shortPass } + + //password == username + if (password.toLowerCase()==username.toLowerCase()) return badPass + + //password length + score += password.length * 4 + score += ( checkRepetition(1,password).length - password.length ) * 1 + score += ( checkRepetition(2,password).length - password.length ) * 1 + score += ( checkRepetition(3,password).length - password.length ) * 1 + score += ( checkRepetition(4,password).length - password.length ) * 1 + + //password has 3 numbers + if (password.match(/(.*[0-9].*[0-9].*[0-9])/)) score += 5 + + //password has 2 sybols + if (password.match(/(.*[!,@,#,$,%,^,&,*,?,_,~].*[!,@,#,$,%,^,&,*,?,_,~])/)) score += 5 + + //password has Upper and Lower chars + if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) score += 10 + + //password has number and chars + if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/)) score += 15 + // + //password has number and symbol + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([0-9])/)) score += 15 + + //password has char and symbol + if (password.match(/([!,@,#,$,%,^,&,*,?,_,~])/) && password.match(/([a-zA-Z])/)) score += 15 + + //password is just a nubers or chars + if (password.match(/^\w+$/) || password.match(/^\d+$/) ) score -= 10 + + //verifing 0 < score < 100 + if ( score < 0 ) score = 0 + if ( score > 100 ) score = 100 + + if (score < 34 ) return badPass + if (score < 68 ) return goodPass + return strongPass +} + + +// checkRepetition(1,'aaaaaaabcbc') = 'abcbc' +// checkRepetition(2,'aaaaaaabcbc') = 'aabc' +// checkRepetition(2,'aaaaaaabcdbcd') = 'aabcd' + +function checkRepetition(pLen,str) { + res = "" + for ( i=0; i<str.length ; i++ ) { + repeated=true + for (j=0;j < pLen && (j+i+pLen) < str.length;j++) + repeated=repeated && (str.charAt(j+i)==str.charAt(j+i+pLen)) + if (j<pLen) repeated=false + if (repeated) { + i+=pLen-1 + repeated=false + } + else { + res+=str.charAt(i) + } + } + return res +} diff --git a/wp-admin/js/post.js b/wp-admin/js/post.js new file mode 100644 index 0000000..9aeafcc --- /dev/null +++ b/wp-admin/js/post.js @@ -0,0 +1,157 @@ +// this file contains all the scripts used in the post/edit page + +function new_tag_remove_tag() { + var id = jQuery( this ).attr( 'id' ); + var num = id.substr( 10 ); + var current_tags = jQuery( '#tags-input' ).val().split(','); + delete current_tags[num]; + var new_tags = []; + jQuery.each( current_tags, function( key, val ) { + if ( val && !val.match(/^\s+$/) && '' != val ) { + new_tags = new_tags.concat( val ); + } + }); + jQuery( '#tags-input' ).val( new_tags.join( ',' ).replace( /\s*,+\s*/, ',' ).replace( /,+/, ',' ).replace( /,+\s+,+/, ',' ).replace( /,+\s*$/, '' ).replace( /^\s*,+/, '' ) ); + tag_update_quickclicks(); + jQuery('#newtag').focus(); + return false; +} + +function tag_update_quickclicks() { + var current_tags = jQuery( '#tags-input' ).val().split(','); + jQuery( '#tagchecklist' ).empty(); + shown = false; +// jQuery.merge( current_tags, current_tags ); // this doesn't work anymore, need something to array_unique + jQuery.each( current_tags, function( key, val ) { + val = val.replace( /^\s+/, '' ).replace( /\s+$/, '' ); // trim + if ( !val.match(/^\s+$/) && '' != val ) { + txt = '<span><a id="tag-check-' + key + '" class="ntdelbutton">X</a> ' + val + '</span> '; + jQuery( '#tagchecklist' ).append( txt ); + jQuery( '#tag-check-' + key ).click( new_tag_remove_tag ); + shown = true; + } + }); + if ( shown ) + jQuery( '#tagchecklist' ).prepend( '<strong>'+postL10n.tagsUsed+'</strong><br />' ); +} + +function tag_flush_to_text() { + var newtags = jQuery('#tags-input').val() + ',' + jQuery('#newtag').val(); + // massage + newtags = newtags.replace( /\s+,+\s*/g, ',' ).replace( /,+/g, ',' ).replace( /,+\s+,+/g, ',' ).replace( /,+\s*$/g, '' ).replace( /^\s*,+/g, '' ); + jQuery('#tags-input').val( newtags ); + tag_update_quickclicks(); + jQuery('#newtag').val(''); + jQuery('#newtag').focus(); + return false; +} + +function tag_save_on_publish() { + if ( jQuery('#newtag').val() != postL10n.addTag ) + tag_flush_to_text(); +} + +function tag_press_key( e ) { + if ( 13 == e.keyCode ) { + tag_flush_to_text(); + return false; + } +} + +addLoadEvent( function() { + // postboxes + add_postbox_toggles('post'); + + // If no tags on the page, skip the tag and category stuff. + if ( !jQuery('#tags-input').size() ) { + return; + } + + // Editable slugs + make_slugedit_clickable(); + + // hide advanced slug field + jQuery('#slugdiv').hide(); + + jQuery('#tags-input').hide(); + tag_update_quickclicks(); + // add the quickadd form + jQuery('#jaxtag').prepend('<span id="ajaxtag"><input type="text" name="newtag" id="newtag" class="form-input-tip" size="16" autocomplete="off" value="'+postL10n.addTag+'" /><input type="button" class="button" id="tagadd" value="' + postL10n.add + '"/><input type="hidden"/><input type="hidden"/><span class="howto">'+postL10n.separate+'</span></span>'); + jQuery('#tagadd').click( tag_flush_to_text ); + jQuery('#newtag').focus(function() { + if ( this.value == postL10n.addTag ) + jQuery(this).val( '' ).removeClass( 'form-input-tip' ); + }); + jQuery('#newtag').blur(function() { + if ( this.value == '' ) + jQuery(this).val( postL10n.addTag ).addClass( 'form-input-tip' ); + }); + + // auto-save tags on post save/publish + jQuery('#publish').click( tag_save_on_publish ); + jQuery('#save-post').click( tag_save_on_publish ); + + // auto-suggest stuff + jQuery('#newtag').suggest( 'admin-ajax.php?action=ajax-tag-search', { delay: 500, minchars: 2 } ); + jQuery('#newtag').keypress( tag_press_key ); + + // category tabs + var categoryTabs =jQuery('#category-tabs').tabs(); + + // Ajax Cat + var newCat = jQuery('#newcat').one( 'focus', function() { jQuery(this).val( '' ).removeClass( 'form-input-tip' ) } ); + jQuery('#category-add-sumbit').click( function() { newCat.focus(); } ); + var newCatParent = false; + var newCatParentOption = false; + var noSyncChecks = false; // prophylactic. necessary? + var syncChecks = function() { + if ( noSyncChecks ) + return; + noSyncChecks = true; + var th = jQuery(this); + var c = th.is(':checked'); + var id = th.val().toString(); + jQuery('#in-category-' + id + ', #in-popular-category-' + id).attr( 'checked', c ); + noSyncChecks = false; + }; + var catAddAfter = function( r, s ) { + if ( !newCatParent ) newCatParent = jQuery('#newcat_parent'); + if ( !newCatParentOption ) newCatParentOption = newCatParent.find( 'option[value=-1]' ); + jQuery(s.what + ' response_data', r).each( function() { + var t = jQuery(jQuery(this).text()); + t.find( 'label' ).each( function() { + var th = jQuery(this); + var val = th.find('input').val(); + var id = th.find('input')[0].id + jQuery('#' + id).change( syncChecks ); + if ( newCatParent.find( 'option[value=' + val + ']' ).size() ) + return; + var name = jQuery.trim( th.text() ); + var o = jQuery( '<option value="' + parseInt( val, 10 ) + '"></option>' ).text( name ); + newCatParent.prepend( o ); + } ); + newCatParentOption.attr( 'selected', true ); + } ); + }; + jQuery('#categorychecklist').wpList( { + alt: '', + response: 'category-ajax-response', + addAfter: catAddAfter + } ); + jQuery('#category-add-toggle').click( function() { + jQuery(this).parents('div:first').toggleClass( 'wp-hidden-children' ); + categoryTabs.tabsClick( 1 ); + jQuery('#newcat').focus(); + return false; + } ); + jQuery('.categorychecklist :checkbox').change( syncChecks ).filter( ':checked' ).change(); + + jQuery('.edit-timestamp').click(function () { + if (jQuery('#timestampdiv').is(":hidden")) { + jQuery('#timestampdiv').slideDown("normal"); + } else { + jQuery('#timestampdiv').hide(); + } + return false; + }); +}); diff --git a/wp-admin/js/postbox.js b/wp-admin/js/postbox.js new file mode 100644 index 0000000..a512f4b --- /dev/null +++ b/wp-admin/js/postbox.js @@ -0,0 +1,14 @@ +function add_postbox_toggles(page) { + jQuery('.postbox h3').prepend('<a class="togbox">+</a> '); + jQuery('.postbox h3').click( function() { jQuery(jQuery(this).parent().get(0)).toggleClass('closed'); save_postboxes_state(page); } ); +} + +function save_postboxes_state(page) { + var closed = jQuery('.postbox').filter('.closed').map(function() { return this.id; }).get().join(','); + jQuery.post(postboxL10n.requestFile, { + action: 'closed-postboxes', + closed: closed, + closedpostboxesnonce: jQuery('#closedpostboxesnonce').val(), + page: page + }); +} diff --git a/wp-admin/js/slug.js b/wp-admin/js/slug.js new file mode 100644 index 0000000..f26a5f2 --- /dev/null +++ b/wp-admin/js/slug.js @@ -0,0 +1,48 @@ +function edit_permalink(post_id) { + var i, c = 0; + var e = jQuery('#editable-post-name'); + var revert_e = e.html(); + var real_slug = jQuery('#post_name'); + var revert_slug = real_slug.html(); + var b = jQuery('#edit-slug-buttons'); + var revert_b = b.html(); + var full = jQuery('#editable-post-name-full').html(); + + b.html('<a href="" class="save">'+slugL10n.save+'</a> <a class="cancel" href="">'+slugL10n.cancel+'</a>'); + b.children('.save').click(function() { + var new_slug = e.children('input').val(); + jQuery.post(slugL10n.requestFile, { + action: 'sample-permalink', + post_id: post_id, + new_slug: new_slug, + new_title: jQuery('#title').val(), + samplepermalinknonce: jQuery('#samplepermalinknonce').val()}, function(data) { + jQuery('#edit-slug-box').html(data); + b.html(revert_b); + real_slug.attr('value', new_slug); + make_slugedit_clickable(); + }); + return false; + }); + jQuery('#edit-slug-buttons .cancel').click(function() { + e.html(revert_e); + b.html(revert_b); + real_slug.attr('value', revert_slug); + return false; + }); + for(i=0; i < full.length; ++i) { + if ('%' == full.charAt(i)) c++; + } + slug_value = (c > full.length/4)? '' : full; + e.html('<input type="text" id="new-post-slug" value="'+slug_value+'" />').children('input').keypress(function(e){ + var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0; + // on enter, just save the new slug, don't save the post + if (13 == key) {b.children('.save').click();return false;} + if (27 == key) {b.children('.cancel').click();return false;} + real_slug.attr('value', this.value)}).focus(); +} + +function make_slugedit_clickable() { + jQuery('#editable-post-name').click(function() {jQuery('#edit-slug-buttons').children('.edit-slug').click()}); +} + diff --git a/wp-admin/js/tags.js b/wp-admin/js/tags.js new file mode 100644 index 0000000..37182df --- /dev/null +++ b/wp-admin/js/tags.js @@ -0,0 +1,21 @@ +jQuery(function($) { + var options = false + + var addAfter = function( r, settings ) { + var name = $("<span>" + $('name', r).text() + "</span>").html(); + var id = $('tag', r).attr('id'); + options[options.length] = new Option(name, id); + } + + var delAfter = function( r, settings ) { + var id = $('tag', r).attr('id'); + for ( var o = 0; o < options.length; o++ ) + if ( id == options[o].value ) + options[o] = null; + } + + if ( options ) + $('#the-list').wpList( { addAfter: addAfter, delAfter: delAfter } ); + else + $('#the-list').wpList(); +}); diff --git a/wp-admin/js/widgets.js b/wp-admin/js/widgets.js new file mode 100644 index 0000000..6bf7f2c --- /dev/null +++ b/wp-admin/js/widgets.js @@ -0,0 +1,136 @@ +jQuery(function($) { + $('.noscript-action').remove(); + + var increment = 1; + + // Open or close widget control form + var toggleWidget = function( li, disableFields ) { + var width = li.find('input.widget-width').val(); + + // it seems IE chokes on these animations because of the positioning/floating + var widgetAnim = $.browser.msie ? function() { + var t = $(this); + if ( t.is(':visible') ) { + if ( disableFields ) { t.find( ':enabled' ).not( '[name="widget-id[]"]' ).attr( 'disabled', 'disabled' ); } + li.css( 'marginLeft', 0 ); + t.siblings('h4').children('a').text( widgetsL10n.edit ); + } else { + t.find( ':disabled' ).attr( 'disabled', '' ); // always enable on open + if ( width > 250 ) + li.css( 'marginLeft', ( width - 250 ) * -1 ); + t.siblings('h4').children('a').text( widgetsL10n.cancel ); + } + t.toggle(); + } : function() { + var t = $(this); + + if ( t.is(':visible') ) { + if ( disableFields ) { t.find( ':enabled' ).not( '[name="widget-id[]"]' ).attr( 'disabled', 'disabled' ); } + if ( width > 250 ) + li.animate( { marginLeft: 0 } ); + t.siblings('h4').children('a').text( widgetsL10n.edit ); + } else { + t.find( ':disabled' ).attr( 'disabled', '' ); // always enable on open + if ( width > 250 ) + li.animate( { marginLeft: ( width - 250 ) * -1 } ); + t.siblings('h4').children('a').text( widgetsL10n.cancel ); + } + t.animate( { height: 'toggle' } ); + }; + + return li.children('div.widget-control').each( widgetAnim ).end(); + }; + + // onclick for edit/cancel links + var editClick = function() { + var q = wpAjax.unserialize( this.href ); + // if link is in available widgets list, make sure it points to the current sidebar + if ( ( q.sidebar && q.sidebar == $('#sidebar').val() ) || q.add ) { + var w = q.edit || q.add; + toggleWidget( $('#current-sidebar .widget-control-list input[@name^="widget-id"][@value=' + w + ']').parents('li:first'), false ).blur(); + return false; + } else if ( q.sidebar ) { // otherwise, redirect to correct page + return true; + } + + // If link is in current widgets list, just open the form + toggleWidget( $(this).parents('li:first'), true ).blur(); + return false; + }; + + // onclick for add links + var addClick = function() { + var oldLi = $(this).parents('li:first').find('ul.widget-control-info li'); + var newLi = oldLi.clone(); + + if ( newLi.html().match( /%i%/ ) ) { + // supplid form is a template, replace %i% by unique id + var i = $('#generated-time').val() + increment.toString(); + increment++; + newLi.html( newLi.html().replace( /%i%/g, i ) ); + } else { + $(this).text( widgetsL10n.edit ).unbind().click( editClick ); + // save form content in textarea so we don't have any conflicting HTML ids + oldLi.html( '<textarea>' + oldLi.html() + '</textarea>' ); + } + + // add event handlers + addWidgetControls( newLi ); + + // add widget to sidebar sortable + widgetSortable.append( newLi ).SortableAddItem( newLi[0] ); + + // increment widget counter + var n = parseInt( $('#widget-count').text(), 10 ) + 1; + $('#widget-count').text( n.toString() ) + + return false; + }; + + // add event handlers to all links found in context + var addWidgetControls = function( context ) { + if ( !context ) + context = document; + + $('a.widget-control-edit', context).click( editClick ); + + // onclick for save links + $('a.widget-control-save', context).click( function() { + toggleWidget( $(this).parents('li:first'), false ).blur() + return false; + } ); + + // onclick for remove links + $('a.widget-control-remove', context).click( function() { + var w = $(this).parents('li:first').find('input[@name^="widget-id"]').val(); + $(this).parents('li:first').remove(); + var t = $('#widget-list ul#widget-control-info-' + w + ' textarea'); + t.parent().html( t.text() ).parents('li.widget-list-item:first').children( 'h4' ).children('a.widget-action') + .show().text( widgetsL10n.add ).unbind().click( addClick ); + var n = parseInt( $('#widget-count').text(), 10 ) - 1; + $('#widget-count').text( n.toString() ) + return false; + } ); + } + + addWidgetControls(); + + $('a.widget-control-add').click( addClick ); + + var widgetSortable; + var widgetSortableInit = function() { + try { // a hack to make sortables work in jQuery 1.2+ and IE7 + $('#current-sidebar .widget-control-list').SortableDestroy(); + } catch(e) {} + widgetSortable = $('#current-sidebar .widget-control-list').Sortable( { + accept: 'widget-sortable', + helperclass: 'sorthelper', + handle: 'h4.widget-title', + onStop: widgetSortableInit + } ); + } + + // initialize sortable + widgetSortableInit(); + +}); diff --git a/wp-admin/media-upload.php b/wp-admin/media-upload.php new file mode 100644 index 0000000..e756166 --- /dev/null +++ b/wp-admin/media-upload.php @@ -0,0 +1,41 @@ +<?php +require_once('admin.php'); +wp_enqueue_script('swfupload'); +wp_enqueue_script('swfupload-degrade'); +wp_enqueue_script('swfupload-queue'); +wp_enqueue_script('swfupload-handlers'); + +@header('Content-Type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset')); + +if (!current_user_can('upload_files')) + wp_die(__('You do not have permission to upload files.')); + +// IDs should be integers +$ID = isset($ID)? (int) $ID : 0; +$post_id = isset($post_id)? (int) $post_id : 0; + +// Require an ID for the edit screen +if ( isset($action) && $action == 'edit' && !$ID ) + wp_die(__("You are not allowed to be here")); + +// upload type: image, video, file, ..? +if ( isset($_GET['type']) ) + $type = strval($_GET['type']); +else + $type = apply_filters('media_upload_default_type', 'file'); + +// tab: gallery, library, or type-specific +if ( isset($_GET['tab']) ) + $tab = strval($_GET['tab']); +else + $tab = apply_filters('media_upload_default_tab', 'type'); + +$body_id = 'media-upload'; + +// let the action code decide how to handle the request +if ( $tab == 'type' ) + do_action("media_upload_$type"); +else + do_action("media_upload_$tab"); + +?> diff --git a/wp-admin/media.php b/wp-admin/media.php new file mode 100644 index 0000000..bd64104 --- /dev/null +++ b/wp-admin/media.php @@ -0,0 +1,87 @@ +<?php + +require_once('admin.php'); + +$parent_file = 'edit.php'; +$submenu_file = 'upload.php'; + +wp_reset_vars(array('action')); + +switch( $action ) : +case 'upload' : +case 'delete' : break; // stubs +case 'editattachment' : + $errors = media_upload_form_handler(); + if ( empty($errors) ) { + wp_redirect( add_query_arg( 'message', 'updated' ) ); + exit; + break; + } + // no break +case 'edit' : + $title = __('Edit Media'); + + if ( empty($errors) ) + $errors = null; + + if ( empty( $_GET['attachment_id'] ) ) { + wp_redirect('upload.php'); + exit(); + } + $att_id = (int) $_GET['attachment_id']; + $att = get_post($att_id); + + add_filter('attachment_fields_to_edit', 'media_single_attachment_fields_to_edit', 10, 2); + + wp_enqueue_script( 'wp-ajax-response' ); + add_action('admin_head', 'media_admin_css'); + + require( 'admin-header.php' ); + + $message = ''; + $class = ''; + if ( isset($_GET['message']) ) { + switch ( $_GET['message'] ) : + case 'updated' : + $message = __('Media attachment updated.'); + $class = 'updated fade'; + break; + endswitch; + } + if ( $message ) + echo "<div id='message' class='$class'><p>$message</p></div>\n"; + +?> + +<div class="wrap"> + +<h2><?php _e( 'Edit Media' ); ?></h2> + +<form method="post" action="<?php echo clean_url( remove_query_arg( 'message' ) ); ?>" class="media-upload-form" id="media-single-form"> +<div id="media-items" class="media-single"> +<div id='media-item-<?php echo $att_id; ?>' class='media-item'> +<?php echo get_media_item( $att_id, array( 'toggle' => false, 'send' => false, 'delete' => false, 'errors' => $errors ) ); ?> +</div> +</div> + +<p class="submit"> +<input type="submit" class="button" name="save" value="<?php _e('Save Changes'); ?>" /> +<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" /> +<input type="hidden" name="action" value="editattachment" /> +<?php wp_nonce_field('media-form'); ?> +</p> + + +</div> + +<?php + + require( 'admin-footer.php' ); + + break; +endswitch; + +wp_redirect( 'upload.php' ); +exit; + +?> diff --git a/wp-admin/update.php b/wp-admin/update.php new file mode 100644 index 0000000..b047384 --- /dev/null +++ b/wp-admin/update.php @@ -0,0 +1,127 @@ +<?php + +require_once('admin.php'); + +if ( !current_user_can('edit_plugins') ) + wp_die('<p>'.__('You do not have sufficient permissions to update plugins for this blog.').'</p>'); + +function request_filesystem_credentials($form_post, $type = '', $error = false) { + if ( empty($type) ) + $type = get_filesystem_method(); + + if ( 'direct' == $type ) + return array(); + + if ( ! $error && !empty($_POST['password']) && !empty($_POST['username']) && !empty($_POST['hostname']) ) { + $credentials = array('hostname' => $_POST['hostname'], 'username' => $_POST['username'], + 'password' => $_POST['password'], 'ssl' => $_POST['ssl']); + $stored_credentials = $credentials; + unset($stored_credentials['password']); + update_option('ftp_credentials', $stored_credentials); + return $credentials; + } + $hostname = ''; + $username = ''; + $password = ''; + $ssl = ''; + if ( $credentials = get_option('ftp_credentials') ) + extract($credentials, EXTR_OVERWRITE); + if( $error ){ + echo '<div id="message" class="error"><p>' . __('<strong>Error:</strong> There was an error connecting to the server, Please verify the settings are correct.') . '</p></div>'; + } +?> +<form action="<?php echo $form_post ?>" method="post"> +<div class="wrap"> +<h2><?php _e('FTP Connection Information') ?></h2> +<p><?php _e('To perform the requested update, FTP connection information is required.') ?></p> +<table class="form-table"> +<tr valign="top"> +<th scope="row"><?php _e('Hostname:') ?></th> +<td><input name="hostname" type="text" id="hostname" value="<?php echo attribute_escape($hostname) ?>" size="40" /></td> +</tr> +<tr valign="top"> +<th scope="row"><?php _e('Username:') ?></th> +<td><input name="username" type="text" id="username" value="<?php echo attribute_escape($username) ?>" size="40" /></td> +</tr> +<tr valign="top"> +<th scope="row"><?php _e('Password:') ?></th> +<td><input name="password" type="password" id="password" value="<?php echo attribute_escape($password) ?>" size="40" /></td> +</tr> +<tr valign="top"> +<th scope="row"><?php _e('Use SSL:') ?></th> +<td> +<select name="ssl" id="ssl"> +<?php +foreach ( array(0 => __('No'), 1 => __('Yes')) as $key => $value ) : + $selected = ($ssl == $value) ? 'selected="selected"' : ''; + echo "\n\t<option value='$key' $selected>" . $value . '</option>'; +endforeach; +?> +</select> +</td> +</tr> +</table> +<p class="submit"> +<input type="submit" name="submit" value="<?php _e('Proceed'); ?>" /> +</p> +</div> +</form> +<?php + return false; +} + +function show_message($message) { + if( is_wp_error($message) ){ + if( $message->get_error_data() ) + $message = $message->get_error_message() . ': ' . $message->get_error_data(); + else + $message = $message->get_error_message(); + } + echo "<p>$message</p>"; +} + +function do_plugin_upgrade($plugin) { + global $wp_filesystem; + + $url = wp_nonce_url("update.php?action=upgrade-plugin&plugin=$plugin", "upgrade-plugin_$plugin"); + if ( false === ($credentials = request_filesystem_credentials($url)) ) + return; + + if( ! WP_Filesystem($credentials) ){ + request_filesystem_credentials($url, '', true); //Failed to connect, Error and request again + return; + } + + echo '<div class="wrap">'; + echo '<h2>' . __('Upgrade Plugin') . '</h2>'; + if ( $wp_filesystem->errors->get_error_code() ) { + foreach ( $wp_filesystem->errors->get_error_messages() as $message ) + show_message($message); + echo '</div>'; + return; + } + + $result = wp_update_plugin($plugin, 'show_message'); + + if ( is_wp_error($result) ) + show_message($result); + else + echo __('Plugin upgraded successfully'); + echo '</div>'; +} + +if ( isset($_GET['action']) ) { + if ( isset($_GET['plugin']) ) + $plugin = trim($_GET['plugin']); + + if ( 'upgrade-plugin' == $_GET['action'] ) { + check_admin_referer('upgrade-plugin_' . $plugin); + $title = __('Upgrade Plugin'); + $parent_file = 'plugins.php'; + require_once('admin-header.php'); + do_plugin_upgrade($plugin); + include('admin-footer.php'); + } +} + +?> diff --git a/wp-admin/wpmu-blogs.php.rej b/wp-admin/wpmu-blogs.php.rej new file mode 100644 index 0000000..c3aebfd --- /dev/null +++ b/wp-admin/wpmu-blogs.php.rej @@ -0,0 +1,1224 @@ +*************** +*** 1,570 **** + <?php + require_once('admin.php'); + +- $title = __('WPMU Admin: Blogs'); + $parent_file = 'wpmu-admin.php'; + require_once('admin-header.php'); + if( is_site_admin() == false ) { +- die( __('<p>You do not have permission to access this page.</p>') ); + } +- if (isset($_GET['updated'])) { +- ?><div id="message" class="updated fade"><p><?php _e('Options saved.') ?></p></div><?php +- } +- print '<div class="wrap">'; +- switch( $_GET[ 'action' ] ) { +- case "editblog": +- $id = intval( $_GET[ 'id' ] ); +- $options_table_name = "$wpmuBaseTablePrefix{$id}_options"; +- $options = $wpdb->get_results( "SELECT * FROM {$options_table_name} WHERE option_name NOT LIKE 'rss%' AND option_name NOT LIKE '%user_roles'", ARRAY_A ); +- $details = $wpdb->get_row( "SELECT * FROM {$wpdb->blogs} WHERE blog_id = '{$id}'", ARRAY_A ); +- $editblog_roles = get_blog_option( $id, "$wpmuBaseTablePrefix{$id}_user_roles" ); + +- print "<h2>" . __('Edit Blog') . "</h2>"; +- print "<a href='http://{$details[ 'domain' ]}/'>{$details[ 'domain' ]}</a>"; +- ?> +- <form name="form1" method="post" action="wpmu-edit.php?action=updateblog"> +- <?php wp_nonce_field( "editblog" ); ?> +- <input type="hidden" name="id" value="<?php echo $id ?>" /> +- <table><td valign='top'> +- <div class="wrap"> +- <table width="100%" border='0' cellspacing="2" cellpadding="5" class="editform"> +- <tr valign="top"> +- <th scope="row"><?php _e('URL') ?></th> +- <td>http://<input name="blog[domain]" type="text" id="domain" value="<?php echo $details[ 'domain' ] ?>" size="33" /></td> +- </tr> +- <tr valign="top"> +- <th scope="row"><?php _e('Path') ?></th> +- <td><input name="blog[path]" type="text" id="path" value="<?php echo $details[ 'path' ] ?>" size="40" /></td> +- </tr> +- <tr valign="top"> +- <th scope="row"><?php _e('Registered') ?></th> +- <td><input name="blog[registered]" type="text" id="blog_registered" value="<?php echo $details[ 'registered' ] ?>" size="40" /></td> +- </tr> +- <tr valign="top"> +- <th scope="row"><?php _e('Last Updated') ?></th> +- <td><input name="blog[last_updated]" type="text" id="blog_last_updated" value="<?php echo $details[ 'last_updated' ] ?>" size="40" /></td> +- </tr> +- <tr valign="top"> +- <th scope="row"><?php _e('Public') ?></th> +- <td><input type='radio' name='blog[public]' value='1' <?php if( $details[ 'public' ] == '1' ) echo " checked"?>> <?php _e('Yes') ?> +- <input type='radio' name='blog[public]' value='0' <?php if( $details[ 'public' ] == '0' ) echo " checked"?>> <?php _e('No') ?> +- </td> +- </tr> +- <tr valign="top"> +- <th scope="row"><?php _e( 'Archived' ); ?></th> +- <td><input type='radio' name='blog[archived]' value='1' <?php if( $details[ 'archived' ] == '1' ) echo " checked"?>> <?php _e('Yes') ?> +- <input type='radio' name='blog[archived]' value='0' <?php if( $details[ 'archived' ] == '0' ) echo " checked"?>> <?php _e('No') ?> +- </td> +- </tr> +- <tr valign="top"> +- <th scope="row"><?php _e( 'Mature' ); ?></th> +- <td><input type='radio' name='blog[mature]' value='1' <?php if( $details[ 'mature' ] == '1' ) echo " checked"?>> <?php _e('Yes') ?> +- <input type='radio' name='blog[mature]' value='0' <?php if( $details[ 'mature' ] == '0' ) echo " checked"?>> <?php _e('No') ?> +- </td> +- </tr> +- <tr valign="top"> +- <th scope="row"><?php _e( 'Spam' ); ?></th> +- <td><input type='radio' name='blog[spam]' value='1' <?php if( $details[ 'spam' ] == '1' ) echo " checked"?>> <?php _e('Yes') ?> +- <input type='radio' name='blog[spam]' value='0' <?php if( $details[ 'spam' ] == '0' ) echo " checked"?>> <?php _e('No') ?> +- </td> +- </tr> +- <tr valign="top"> +- <th scope="row"><?php _e( 'Deleted' ); ?></th> +- <td><input type='radio' name='blog[deleted]' value='1' <?php if( $details[ 'deleted' ] == '1' ) echo " checked"?>> <?php _e('Yes') ?> +- <input type='radio' name='blog[deleted]' value='0' <?php if( $details[ 'deleted' ] == '0' ) echo " checked"?>> <?php _e('No') ?> +- </td> +- </tr> +- <tr><td colspan='2'> +- <br /> +- <br /> +- </td></tr> +- <?php +- $editblog_default_role = 'subscriber'; +- while( list( $key, $val ) = each( $options ) ) { +- if( $val[ 'option_name' ] == 'default_role' ) +- $editblog_default_role = $val[ 'option_value' ]; +- $disabled = ''; +- if ( is_serialized($val[ 'option_value' ]) ) { +- if ( is_serialized_string($val[ 'option_value' ]) ) { +- $val[ 'option_value' ] = wp_specialchars(maybe_unserialize($val[ 'option_value' ]), 'single'); +- } else { +- $val[ 'option_value' ] = "SERIALIZED DATA"; +- $disabled = ' disabled="disabled"'; +- } + } +- if ( stristr($val[ 'option_value' ], "\r") or stristr($val[ 'option_value' ], "\n") or stristr($val[ 'option_value' ], "\r\n") ) { + ?> +- <tr valign="top"> +- <th scope="row"><?php echo ucwords( str_replace( "_", " ", $val[ 'option_name' ] ) ) ?></th> +- <td><textarea rows="5" cols="40" name="option[<?php echo $val[ 'option_name' ] ?>]" type="text" id="<?php echo $val[ 'option_name' ] ?>"<?php echo $disabled ?>><?php echo wp_specialchars( stripslashes( $val[ 'option_value' ] ), 1 ) ?></textarea></td> +- </tr> +- <?php +- } else { + ?> +- <tr valign="top"> +- <th scope="row"><?php echo ucwords( str_replace( "_", " ", $val[ 'option_name' ] ) ) ?></th> +- <td><input name="option[<?php echo $val[ 'option_name' ] ?>]" type="text" id="<?php echo $val[ 'option_name' ] ?>" value="<?php echo wp_specialchars( stripslashes( $val[ 'option_value' ] ), 1 ) ?>" size="40" <?php echo $disabled ?>/></td> +- </tr> + <?php +- } +- } +- ?> +- </table> +- <p class="submit"> +- <input type="submit" name="Submit" value="<?php _e('Update Options') ?> »" /> +- </p> +- </div> +- </td> +- <td valign='top'> +- <?php +- $themes = get_themes(); +- $blog_allowed_themes = wpmu_get_blog_allowedthemes( $id ); +- $allowed_themes = get_site_option( "allowedthemes" ); +- if( $allowed_themes == false ) { +- $allowed_themes = array_keys( $themes ); +- } +- $out = ''; +- foreach( $themes as $key => $theme ) { +- $theme_key = wp_specialchars( $theme[ 'Stylesheet' ] ); +- if( isset( $allowed_themes[ $theme_key ] ) == false ) { +- if( isset( $blog_allowed_themes[ $theme_key ] ) == true ) { +- $checked = 'checked '; +- } else { +- $checked = ''; +- } +- +- $out .= ' +- <tr valign="top"> +- <th title="' . htmlspecialchars( $theme[ "Description" ] ) . '" scope="row">'.$key.'</th> +- <td><input name="theme['.$theme_key.']" type="checkbox" id="'.$key.'" value="on" '.$checked.'/></td> +- </tr> '; +- } +- } +- if( $out != '' ) { +- print "<div class='wrap'><h3>" . __('Blog Themes') . "</h3>"; +- print '<table width="100%" border="0" cellspacing="2" cellpadding="5" class="editform">'; +- print '<tr><th>' . __('Theme') . '</th><th>' . __('Enable') . '</th></tr>'; +- print $out; +- print "</table></div>"; +- } +- $blogusers = get_users_of_blog( $id ); +- print '<div class="wrap"><h3>' . __('Blog Users') . '</h3>'; +- if( is_array( $blogusers ) ) { +- print '<table width="100%"><caption>' . __('Current Users') . '</caption>'; +- print "<tr><th>" . __('User') . "</th><th>" . __('Role') . "</th><th>" . __('Password') . "</th><th>" . __('Remove') . "</th><th></th></tr>"; +- reset( $blogusers ); +- while( list( $key, $val ) = each( $blogusers ) ) +- { +- $t = @unserialize( $val->meta_value ); +- if( is_array( $t ) ) { +- reset( $t ); +- $existing_role = key( $t ); +- } +- print "<tr><td>" . $val->user_login . "</td>"; +- if( $val->user_id != $current_user->data->ID ) { +- ?> +- <td><select name="role[<?php echo $val->user_id ?>]" id="new_role"><?php +- foreach( $editblog_roles as $role => $role_assoc ){ +- $selected = ''; +- if( $role == $existing_role ) +- $selected = 'selected="selected"'; +- echo "<option {$selected} value=\"{$role}\">{$role_assoc['name']}</option>"; +- } +- ?></select></td><td><input type='text' name='user_password[<?php echo $val->user_id ?>]'></td><?php +- print '<td><input title="' . __('Click to remove user') . '" type="checkbox" name="blogusers[' . $val->user_id . ']"></td>'; +- } else { +- print "<td><b>" . __ ('N/A') . "</b></td><td><b>" . __ ('N/A') . "</b></td><td><b>" . __('N/A') . "</b></td>"; +- } +- print '<td><a href="user-edit.php?user_id=' . $val->user_id . '">' . __('Edit') . "</td></tr>"; +- } +- print "</table>"; +- } +- print "<h3>" . __('Add a new user') . "</h3>"; +- ?> +- <p><?php _e('As you type WordPress will offer you a choice of usernames.<br /> Click them to select and hit <em>Update Options</em> to add the user.') ?></p> +- <table> +- <tr><th scope="row"><?php _e('User Login:') ?> </th><td><input type="text" name="newuser" id="newuser"></td></tr> +- <tr><td></td><td></td> </tr> +- <tr> +- <th scope="row"><?php _e('Role:') ?></th> +- <td><select name="new_role" id="new_role"><?php +- reset( $editblog_roles ); +- foreach( $editblog_roles as $role => $role_assoc ){ +- $selected = ''; +- if( $role == $editblog_default_role ) +- $selected = 'selected="selected"'; +- echo "<option {$selected} value=\"{$role}\">{$role_assoc['name']}</option>"; +- } +- ?></select></td> +- </tr> +- </table> +- </div> +- <div class='wrap'><strong><?php _e('Misc Blog Actions') ?></strong> +- <p><?php do_action( "wpmueditblogaction", $_GET[ 'id' ] ); ?></p> +- </div> +- <p class="submit"> +- <input type="submit" name="Submit" value="<?php _e('Update Options') ?> »" /> +- </p> +- +- </td> +- </table> +- <?php +- break; +- default: +- if( isset( $_GET[ 'start' ] ) == false ) { +- $start = 0; +- } else { +- $start = intval( $_GET[ 'start' ] ); +- } +- if( isset( $_GET[ 'num' ] ) == false ) { +- $num = 60; +- } else { +- $num = intval( $_GET[ 'num' ] ); +- } +- +- $query = "SELECT * +- FROM ".$wpdb->blogs." +- WHERE site_id = '".$wpdb->siteid."' "; +- if( $_GET[ 's' ] != '' ) { + $query = "SELECT blog_id, {$wpdb->blogs}.domain, {$wpdb->blogs}.path, registered, last_updated +- FROM $wpdb->blogs, $wpdb->site +- WHERE site_id = '$wpdb->siteid' +- AND {$wpdb->blogs}.site_id = {$wpdb->site}.id +- AND ( {$wpdb->blogs}.domain LIKE '%". trim( $_GET[ 's' ] )."%' OR {$wpdb->blogs}.path LIKE '%". trim( $_GET[ 's' ] )."%' )"; +- } elseif( $_GET[ 'blog_id' ] != '' ) { + $query = "SELECT * +- FROM $wpdb->blogs +- WHERE site_id = '$wpdb->siteid' +- AND blog_id = '".intval($_GET[ 'blog_id' ])."'"; +- } elseif( $_GET[ 'ip_address' ] != '' ) { +- $query = "SELECT * +- FROM $wpdb->blogs, wp_registration_log +- WHERE site_id = '$wpdb->siteid' +- AND {$wpdb->blogs}.blog_id = wp_registration_log.blog_id +- AND wp_registration_log.IP LIKE ('%".$_GET[ 'ip_address' ]."%')"; + } +- if( isset( $_GET[ 'sortby' ] ) == false ) { +- $_GET[ 'sortby' ] = 'id'; + } +- if( $_GET[ 'sortby' ] == 'registered' ) { + $query .= ' ORDER BY registered '; +- } elseif( $_GET[ 'sortby' ] == 'id' ) { + $query .= ' ORDER BY ' . $wpdb->blogs . '.blog_id '; +- } elseif( $_GET[ 'sortby' ] == 'lastupdated' ) { + $query .= ' ORDER BY last_updated '; +- } elseif( $_GET[ 'sortby' ] == 'blogname' ) { + $query .= ' ORDER BY domain '; + } +- if( $_GET[ 'order' ] == 'DESC' ) { +- $query .= "DESC"; +- } else { +- $query .= "ASC"; + } + +- if ( $_GET[ 'ip_address' ] == '' ) +- $query .= " LIMIT " . intval( $start ) . ", " . intval( $num ); +- $blog_list = $wpdb->get_results( $query, ARRAY_A ); +- if( count( $blog_list ) < $num ) { +- $next = false; + } else { +- $next = true; + } +- ?> +- <script language="javascript"> +- <!-- +- var checkflag = "false"; +- function check_all_rows() { +- field = document.formlist; +- if (checkflag == "false") { +- for (i = 0; i < field.length; i++) { +- if( field[i].name == 'allblogs[]' ) +- field[i].checked = true;} +- checkflag = "true"; +- return "<?php _e('Uncheck All') ?>"; +- } else { +- for (i = 0; i < field.length; i++) { +- if( field[i].name == 'allblogs[]' ) +- field[i].checked = false; } +- checkflag = "false"; +- return "<?php _e('Check All') ?>"; +- } +- } + +- // --> +- </script> + +- <h2><?php _e('Blogs') ?></h2> +- <form name="searchform" action="wpmu-blogs.php" method="get" style="float: left; margin-right: 3em;"> +- <table><td> +- <fieldset> +- <legend><?php _e('Search Blogs…') ?></legend> +- <input type='hidden' name='action' value='blogs'> +- <?php _e('Name:') ?> <input type="text" name="s" value="<?php if (isset($_GET[ 's' ])) echo wp_specialchars($_GET[ 's' ], 1); ?>" size="17" /><br /> +- <?php _e('Blog ID:') ?> <input type="text" name="blog_id" value="<?php if (isset($_GET[ 'blog_id' ])) echo wp_specialchars($_GET[ 'blog_id' ], 1); ?>" size="10" /><br /> +- <?php _e('IP Address:') ?> <input type="text" name="ip_address" value="<?php if (isset($_GET[ 'ip_address' ])) echo wp_specialchars($_GET[ 'ip_address' ], 1); ?>" size="10" /><br /> +- <input type="submit" name="submit" value="<?php _e('Search') ?>" /> +- </fieldset> +- <?php +- if( isset($_GET[ 's' ]) && $_GET[ 's' ] != '' ) { +- ?><a href="/wp-admin/wpmu-users.php?action=users&s=<?php echo wp_specialchars($_GET[ 's' ], 1) ?>"><?php _e('Search Users:') ?> <?php echo wp_specialchars($_GET[ 's' ], 1) ?></a><?php +- } +- ?> +- </td><td valign='top'> +- <fieldset> +- <legend><?php _e('Blog Navigation') ?></legend> +- <?php + +- $url2 = "order=" . $_GET[ 'order' ] . "&sortby=" . $_GET[ 'sortby' ] . "&s=" . $_GET[ 's' ] . "&ip_address=" . $_GET[ 'ip_address' ]; + +- $blog_navigation = ''; +- if( $start == 0 ) { +- $blog_navigation .= __('Previous Blogs'); +- } elseif( $start <= 30 ) { +- $blog_navigation .= '<a href="wpmu-blogs.php?start=0&' . $url2 . ' ">' . __('Previous Blogs') . '</a>'; +- } else { +- $blog_navigation .= '<a href="wpmu-blogs.php?start=' . ( $start - $num ) . '&' . $url2 . '">' . __('Previous Blogs') . '</a>'; +- } +- if ( $next ) { +- $blog_navigation .= ' || <a href="wpmu-blogs.php?start=' . ( $start + $num ) . '&' . $url2 . '">' . __('Next Blogs') . '</a>'; +- } else { +- $blog_navigation .= ' || ' . __('Next Blogs'); +- } +- echo $blog_navigation; +- ?> +- </fieldset> +- </td></table> +- </form> + +- <br style="clear:both;" /> + +- <?php + +- // define the columns to display, the syntax is 'internal name' => 'display name' +- $posts_columns = array( +- 'id' => __('ID'), +- 'blogname' => __('Blog Name'), +- 'lastupdated' => __('Last Updated'), +- 'registered' => __('Registered'), +- 'users' => __('Users'), +- 'plugins' => __('Actions') +- ); +- $posts_columns = apply_filters('manage_posts_columns', $posts_columns); + +- // you can not edit these at the moment +- $posts_columns['control_view'] = ''; +- $posts_columns['control_edit'] = ''; +- $posts_columns['control_backend'] = ''; +- $posts_columns['control_deactivate'] = ''; +- $posts_columns['control_archive'] = ''; +- $posts_columns['control_spam'] = ''; +- $posts_columns['control_delete'] = ''; + +- $sortby_url = "s=" . $_GET[ 's' ] . "&ip_address=" . $_GET[ 'ip_address' ]; +- ?> + +- <form name='formlist' action='wpmu-edit.php?action=allblogs' method='POST'> +- <input type=button value="<?php _e('Check All') ?>" onClick="this.value=check_all_rows()"> +- <table width="100%" cellpadding="3" cellspacing="3"> +- <tr> + +- <?php foreach($posts_columns as $column_id => $column_display_name) { ?> +- <th scope="col"><a href="wpmu-blogs.php?<?php echo $sortby_url ?>&sortby=<?php echo $column_id ?>&<?php if( $_GET[ 'sortby' ] == $column_id ) { if( $_GET[ 'order' ] == 'DESC' ) { echo "order=ASC&" ; } else { echo "order=DESC&"; } } ?>start=<?php echo $start ?>"><?php echo $column_display_name; ?></a></th> +- <?php } ?> + +- </tr> +- <?php +- if ($blog_list) { +- $bgcolor = ''; +- $status_list = array( "archived" => "#fee", "spam" => "#faa", "deleted" => "#f55" ); +- foreach ($blog_list as $blog) { +- $class = ('alternate' == $class) ? '' : 'alternate'; +- reset( $status_list ); +- $bgcolour = ""; +- while( list( $status, $col ) = each( $status_list ) ) { +- if( get_blog_status( $blog[ 'blog_id' ], $status ) == 1 ) { +- $bgcolour = "style='background: $col'"; +- } +- } +- print "<tr $bgcolour class='$class'>"; +- if( constant( "VHOST" ) == 'yes' ) { +- $blogname = str_replace( '.' . $current_site->domain, '', $blog[ 'domain' ] ); +- } else { +- $blogname = $blog[ 'path' ]; +- } + +- foreach($posts_columns as $column_name=>$column_display_name) { + +- switch($column_name) { +- +- case 'id': +- ?> +- <th scope="row"><input type='checkbox' id='<?php echo $blog[ 'blog_id' ] ?>' name='allblogs[]' value='<?php echo $blog[ 'blog_id' ] ?>'> <label for='<?php echo $blog[ 'blog_id' ] ?>'><?php echo $blog[ 'blog_id' ] ?></label></th> +- <?php +- break; + +- case 'blogname': +- ?> +- <td valign='top'><label for='<?php echo $blog[ 'blog_id' ] ?>'><?php echo $blogname ?></label> +- </td> +- <?php +- break; + +- case 'lastupdated': +- ?> +- <td valign='top'><?php echo $blog[ 'last_updated' ] == '0000-00-00 00:00:00' ? __("Never") : $blog[ 'last_updated' ] ?></td> +- <?php +- break; + +- case 'registered': +- ?> +- <td valign='top'><?php echo $blog[ 'registered' ] ?></td> +- <?php +- break; +- +- case 'users': +- ?> +- <td valign='top'><?php +- $blogusers = get_users_of_blog( $blog[ 'blog_id' ] ); +- if( is_array( $blogusers ) ) { +- if( $blog[ 'blog_id' ] == 1 && count( $blogusers ) > 10 ) +- $blogusers = array_slice( $blogusers, 0, 10 ); +- while( list( $key, $val ) = each( $blogusers ) ) +- print '<a href="user-edit.php?user_id=' . $val->user_id . '">' . $val->user_login . '</a> ('.$val->user_email.')<BR>'; +- } +- ?></td> +- <?php +- break; +- +- case 'control_view': +- ?> +- <td valign='top'><a href="http://<?php echo $blog[ 'domain' ]. $blog[ 'path' ]; ?>" rel="permalink" class="edit"><?php _e('View'); ?></a></td> +- <?php +- break; +- +- case 'control_edit': +- ?> +- <td valign='top'><?php echo "<a href='wpmu-blogs.php?action=editblog&id=".$blog[ 'blog_id' ]."' class='edit'>" . __('Edit') . "</a>"; ?></td> +- <?php +- break; +- +- case 'control_backend': +- ?> +- <td valign='top'><?php echo "<a href='http://" . $blog[ 'domain' ] . $blog[ 'path' ] . "wp-admin/' class='edit'>" . __('Backend') . "</a>"; ?></td> +- <?php +- break; +- +- case 'control_spam': +- if( get_blog_status( $blog[ 'blog_id' ], "spam" ) == '1' ) { +- ?> +- <td valign='top'><a class='edit' href="wpmu-edit.php?action=confirm&action2=unspamblog&id=<?php echo $blog[ 'blog_id' ] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to unspam the blog %s" ), $blogname ) ) ?>"><?php _e("Not Spam") ?></a></td> + <?php +- } else { + ?> +- <td valign='top'><a class='edit' href="wpmu-edit.php?action=confirm&action2=spamblog&id=<?php echo $blog[ 'blog_id' ] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to mark the blog %s as spam" ), $blogname ) ) ?>"><?php _e("Spam") ?></a></td> +- <?php +- } +- break; + +- case 'control_deactivate': +- if( get_blog_status( $blog[ 'blog_id' ], "deleted" ) == '1' ) { +- ?> +- <td valign='top'><a class='edit' href="wpmu-edit.php?action=confirm&action2=activateblog&ref=<?php echo urlencode( $_SERVER[ 'REQUEST_URI' ] ) ?>&id=<?php echo $blog[ 'blog_id' ] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to activate the blog %s" ), $blogname ) ) ?>"><?php _e("Activate") ?></a></td> +- <?php +- } else { +- ?> +- <td valign='top'><a class='edit' href="wpmu-edit.php?action=confirm&action2=deactivateblog&ref=<?php echo urlencode( $_SERVER[ 'REQUEST_URI' ] ) ?>&id=<?php echo $blog[ 'blog_id' ] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to deactivate the blog %s" ), $blogname ) ) ?>"><?php _e("Deactivate") ?></a></td> +- <?php +- } +- break; +- +- case 'control_archive': +- if( get_blog_status( $blog[ 'blog_id' ], "archived" ) == '1' ) { +- ?> +- <td valign='top'><a class='edit' href="wpmu-edit.php?action=confirm&action2=unarchiveblog&id=<?php echo $blog[ 'blog_id' ] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to unarchive the blog %s" ), $blogname ) ) ?>"><?php _e("Unarchive") ?></a></td> +- <?php +- } else { +- ?> +- <td valign='top'><a class='edit' href="wpmu-edit.php?action=confirm&action2=archiveblog&id=<?php echo $blog[ 'blog_id' ] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to archive the blog %s" ), $blogname ) ) ?>"><?php _e("Archive") ?></a></td> +- <?php +- } +- break; +- +- case 'control_delete': +- ?> +- <td valign='top'><a class='edit' href="wpmu-edit.php?action=confirm&action2=deleteblog&id=<?php echo $blog[ 'blog_id' ] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to delete the blog %s" ), $blogname ) ) ?>"><?php _e("Delete") ?></a></td> + <?php +- break; +- +- case 'plugins': +- ?> +- <td valign='top'><?php do_action( "wpmublogsaction", $blog[ 'blog_id' ] ); ?></td> +- <?php +- break; +- +- default: +- ?> +- <td valign='top'><?php do_action('manage_blogs_custom_column', $column_name, $id); ?></td> +- <?php +- break; +- } +- } +- ?> +- </tr> +- <?php +- } +- } else { +- ?> +- <tr style='background-color: <?php echo $bgcolor; ?>'> +- <td colspan="8"><?php _e('No blogs found.') ?></td> +- </tr> +- <?php +- } // end if ($blogs) +- ?> +- </table> +- <table width='100%'> +- <tr><td width='20%'> +- <input type=button value="<?php _e('Check All') ?>" onClick="this.value=check_all_rows()"> +- <p><?php _e('Selected Blogs:') ?><ul> +- <li><input type='radio' name='blogfunction' id='delete' value='delete'> <label for='delete'><?php _e('Delete') ?></label></li> +- <li><input type='radio' name='blogfunction' id='spam' value='spam'> <label for='spam'><?php _e('Mark as Spam') ?></label></li> +- <?php wp_nonce_field( "allblogs" ); ?> +- </ul> +- <input type='hidden' name='redirect' value='<?php echo $_SERVER[ 'REQUEST_URI' ] ?>'> +- <input type='submit' value='<?php _e('Apply Changes') ?>'></p> +- </form> +- </td><td> +- <fieldset> +- <legend><?php _e('Blog Navigation') ?></legend> +- <?php +- echo $blog_navigation; +- ?> +- </fieldset> +- </td></tr> +- </table> +- </div> +- <div class="wrap"> +- <h2><?php _e('Add Blog') ?></h2> +- <form name="addform" method="post" action="wpmu-edit.php?action=addblog"> +- <?php wp_nonce_field('add-blog') ?> +- <table> +- <tr><th scope='row'><?php _e('Blog Address') ?></th><td><?php +- if( constant( "VHOST" ) == 'yes' ) { +- ?><input name="blog[domain]" type="text" title="<?php _e('Domain') ?>"/>.<?php echo $current_site->domain;?></td></tr><?php +- } else { +- echo $current_site->domain . $current_site->path ?><input name="blog[domain]" type="text" title="<?php _e('Domain') ?>"/></td></tr><?php +- } ?> +- <tr><th scope='row'><?php _e('Blog Title') ?></th><td><input name="blog[title]" type="text" title="<?php _e('Title') ?>"/></td></tr> +- <tr><th scope='row'><?php _e('Admin Email') ?></th><td><input name="blog[email]" type="text" title="<?php _e('Email') ?>"/></td></tr> +- <tr><td colspan='2'><?php _e('A new user will be created if the above email address is not in the database.') ?></td></tr> +- </table> +- <input type="submit" name="go" value="<?php _e('Add Blog') ?>" /> +- </form> +- </div> +- <?php +- +- break; + } // end switch( $action ) +- ?> + +- </div> +- <?php include('admin-footer.php'); ?> +--- 1,651 ---- + <?php + require_once('admin.php'); + ++ $title = __('WordPress MU › Admin › Blogs'); + $parent_file = 'wpmu-admin.php'; ++ wp_enqueue_script( 'listman' ); + require_once('admin-header.php'); ++ + if( is_site_admin() == false ) { ++ wp_die( __('<p>You do not have permission to access this page.</p>') ); + } + ++ $id = intval( $_GET['id'] ); ++ ++ if ( $_GET['updated'] == 'true' ) { ++ ?> ++ <div id="message" class="updated fade"><p> ++ <?php ++ switch ($_GET['action']) { ++ case 'all_spam': ++ _e('Blogs mark as spam !'); ++ break; ++ case 'all_delete': ++ _e('Blogs deleted !'); ++ break; ++ case 'delete': ++ _e('Blog deleted !'); ++ break; ++ case 'add-blog': ++ _e('Blog added !'); ++ break; ++ case 'archive': ++ _e('Blog archived !'); ++ break; ++ case 'unarchive': ++ _e('Blog unarchived !'); ++ break; ++ case 'activate': ++ _e('Blog activated !'); ++ break; ++ case 'deactivate': ++ _e('Blog deactivated !'); ++ break; ++ case 'unspam': ++ _e('Blog mark as not spam !'); ++ break; ++ case 'spam': ++ _e('Blog mark as spam !'); ++ break; ++ case 'umature': ++ _e('Blog mark as not mature !'); ++ break; ++ case 'mature': ++ _e('Blog mark as mature !'); ++ break; ++ default: ++ _e('Options saved !'); ++ break; + } + ?> ++ </p></div> ++ <?php ++ } ++ ++ switch( $_GET['action'] ) { ++ // Edit blog ++ case "editblog": ++ $options = $wpdb->get_results( "SELECT * FROM {$wpmuBaseTablePrefix}{$id}_options WHERE option_name NOT LIKE 'rss%' AND option_name NOT LIKE '%user_roles'", ARRAY_A ); ++ $details = $wpdb->get_row( "SELECT * FROM {$wpdb->blogs} WHERE blog_id = '{$id}'", ARRAY_A ); ++ $editblog_roles = get_blog_option( $id, "{$wpmuBaseTablePrefix}{$id}_user_roles" ); + ?> ++ <div class="wrap"> ++ <h2><?php _e('Edit Blog'); ?></h2> ++ <a href='http://<?php echo $details['domain'].$details['path']; ?>'><?php echo $details['domain'].$details['path']; ?></a> ++ <form method="post" action="wpmu-edit.php?action=updateblog"> ++ <?php wp_nonce_field('editblog'); ?> ++ <input type="hidden" name="id" value="<?php echo $id ?>" /> ++ <table> ++ <tr> ++ <td valign="top"> ++ <div class="wrap"> ++ <table style="border:0; width:100%;" cellspacing="2" cellpadding="5" class="editform"> ++ <tr valign="top"> ++ <th scope="row"><?php _e('URL') ?></th> ++ <td>http://<input name="blog[domain]" type="text" id="domain" value="<?php echo $details['domain'] ?>" size="33" /></td> ++ </tr> ++ <tr valign="top"> ++ <th scope="row"><?php _e('Path') ?></th> ++ <td><input name="blog[path]" type="text" id="path" value="<?php echo $details['path'] ?>" size="40" /></td> ++ </tr> ++ <tr valign="top"> ++ <th scope="row"><?php _e('Registered') ?></th> ++ <td><input name="blog[registered]" type="text" id="blog_registered" value="<?php echo $details['registered'] ?>" size="40" /></td> ++ </tr> ++ <tr valign="top"> ++ <th scope="row"><?php _e('Last Updated') ?></th> ++ <td><input name="blog[last_updated]" type="text" id="blog_last_updated" value="<?php echo $details['last_updated'] ?>" size="40" /></td> ++ </tr> ++ <tr valign="top"> ++ <th scope="row"><?php _e('Public') ?></th> ++ <td> ++ <input type='radio' name='blog[public]' value='1' <?php if( $details['public'] == '1' ) echo 'checked="checked"'; ?> /> <?php _e('Yes') ?> ++ <input type='radio' name='blog[public]' value='0' <?php if( $details['public'] == '0' ) echo 'checked="checked"'; ?> /> <?php _e('No') ?> ++ </td> ++ </tr> ++ <tr valign="top"> ++ <th scope="row"><?php _e( 'Archived' ); ?></th> ++ <td> ++ <input type='radio' name='blog[archived]' value='1' <?php if( $details['archived'] == '1' ) echo 'checked="checked"'; ?> /> <?php _e('Yes') ?> ++ <input type='radio' name='blog[archived]' value='0' <?php if( $details['archived'] == '0' ) echo 'checked="checked"'; ?> /> <?php _e('No') ?> ++ </td> ++ </tr> ++ <tr valign="top"> ++ <th scope="row"><?php _e( 'Mature' ); ?></th> ++ <td> ++ <input type='radio' name='blog[mature]' value='1' <?php if( $details['mature'] == '1' ) echo 'checked="checked"'; ?> /> <?php _e('Yes') ?> ++ <input type='radio' name='blog[mature]' value='0' <?php if( $details['mature'] == '0' ) echo 'checked="checked"'; ?> /> <?php _e('No') ?> ++ </td> ++ </tr> ++ <tr valign="top"> ++ <th scope="row"><?php _e( 'Spam' ); ?></th> ++ <td> ++ <input type='radio' name='blog[spam]' value='1' <?php if( $details['spam'] == '1' ) echo 'checked="checked"'; ?> /> <?php _e('Yes') ?> ++ <input type='radio' name='blog[spam]' value='0' <?php if( $details['spam'] == '0' ) echo 'checked="checked"'; ?> /> <?php _e('No') ?> ++ </td> ++ </tr> ++ <tr valign="top"> ++ <th scope="row"><?php _e( 'Deleted' ); ?></th> ++ <td> ++ <input type='radio' name='blog[deleted]' value='1' <?php if( $details['deleted'] == '1' ) echo 'checked="checked"'; ?> /> <?php _e('Yes') ?> ++ <input type='radio' name='blog[deleted]' value='0' <?php if( $details['deleted'] == '0' ) echo 'checked="checked"'; ?> /> <?php _e('No') ?> ++ </td> ++ </tr> ++ <tr> ++ <td colspan="2"><br /><br /></td> ++ </tr> ++ <?php ++ $editblog_default_role = 'subscriber'; ++ foreach ( $options as $key => $val ) { ++ if( $val['option_name'] == 'default_role' ) { ++ $editblog_default_role = $val['option_value']; ++ } ++ $disabled = ''; ++ if ( is_serialized($val['option_value']) ) { ++ if ( is_serialized_string($val['option_value']) ) { ++ $val['option_value'] = wp_specialchars(maybe_unserialize($val['option_value']), 'single'); ++ } else { ++ $val['option_value'] = "SERIALIZED DATA"; ++ $disabled = ' disabled="disabled"'; ++ } ++ } ++ if ( stristr($val['option_value'], "\r") || stristr($val['option_value'], "\n") || stristr($val['option_value'], "\r\n") ) { ++ ?> ++ <tr valign="top"> ++ <th scope="row"><?php echo ucwords( str_replace( "_", " ", $val['option_name'] ) ) ?></th> ++ <td><textarea rows="5" cols="40" name="option[<?php echo $val['option_name'] ?>]" type="text" id="<?php echo $val['option_name'] ?>"<?php echo $disabled ?>><?php echo wp_specialchars( stripslashes( $val['option_value'] ), 1 ) ?></textarea></td> ++ </tr> ++ <?php ++ } else { ++ ?> ++ <tr valign="top"> ++ <th scope="row"><?php echo ucwords( str_replace( "_", " ", $val['option_name'] ) ) ?></th> ++ <td><input name="option[<?php echo $val['option_name'] ?>]" type="text" id="<?php echo $val['option_name'] ?>" value="<?php echo wp_specialchars( stripslashes( $val['option_value'] ), 1 ) ?>" size="40" <?php echo $disabled ?> /></td> ++ </tr> ++ <?php ++ } ++ } // End foreach ++ ?> ++ </table> ++ <p class="submit"> ++ <input type="submit" name="Submit" value="<?php _e('Update Options »') ?>" /></p> ++ </div> ++ </td> ++ <td valign="top"> ++ <?php ++ // Blog Themes ++ $themes = get_themes(); ++ $blog_allowed_themes = wpmu_get_blog_allowedthemes( $id ); ++ $allowed_themes = get_site_option( "allowedthemes" ); ++ if( $allowed_themes == false ) { ++ $allowed_themes = array_keys( $themes ); ++ } ++ $out = ''; ++ foreach( $themes as $key => $theme ) { ++ $theme_key = wp_specialchars( $theme['Stylesheet'] ); ++ if( isset($allowed_themes[$theme_key] ) == false ) { ++ $checked = ( isset($blog_allowed_themes[ $theme_key ]) ) ? 'checked="checked"' : ''; ++ $out .= '<tr valign="top"> ++ <th title="'.htmlspecialchars( $theme["Description"] ).'" scope="row">'.$key.'</th> ++ <td><input name="theme['.$theme_key.']" type="checkbox" value="on" '.$checked.'/></td> ++ </tr>'; ++ } ++ } ++ ++ if( $out != '' ) { ++ echo "<div class='wrap'><h3>" . __('Blog Themes') . "</h3>"; ++ echo '<table width="100%" border="0" cellspacing="2" cellpadding="5" class="editform">'; ++ echo '<tr><th>' . __('Theme') . '</th><th>' . __('Enable') . '</th></tr>'; ++ echo $out; ++ echo "</table></div>"; ++ } ++ ++ // Blog users ++ $blogusers = get_users_of_blog( $id ); ++ echo '<div class="wrap"><h3>' . __('Blog Users') . '</h3>'; ++ if( is_array( $blogusers ) ) { ++ echo '<table width="100%"><caption>' . __('Current Users') . '</caption>'; ++ echo "<tr><th>" . __('User') . "</th><th>" . __('Role') . "</th><th>" . __('Password') . "</th><th>" . __('Remove') . "</th><th></th></tr>"; ++ reset($blogusers); ++ foreach ( (array) $blogusers as $key => $val ) { ++ $t = @unserialize( $val->meta_value ); ++ if( is_array( $t ) ) { ++ reset( $t ); ++ $existing_role = key( $t ); ++ } ++ echo "<tr><td>" . $val->user_login . "</td>"; ++ if( $val->user_id != $current_user->data->ID ) { ++ ?> ++ <td> ++ <select name="role[<?php echo $val->user_id ?>]" id="new_role"><?php ++ foreach( $editblog_roles as $role => $role_assoc ){ ++ $selected = ( $role == $existing_role ) ? 'selected="selected"' : ''; ++ echo "<option {$selected} value=\"{$role}\">{$role_assoc['name']}</option>"; ++ } ++ ?> ++ </select> ++ </td> ++ <td> ++ <input type='text' name='user_password[<?php echo $val->user_id ?>]' /> ++ </td> ++ <?php ++ echo '<td><input title="' . __('Click to remove user') . '" type="checkbox" name="blogusers[' . $val->user_id . ']" /></td>'; ++ } else { ++ echo "<td><strong>" . __ ('N/A') . "</strong></td><td><strong>" . __ ('N/A') . "</strong></td><td><strong>" . __('N/A') . "</strong></td>"; ++ } ++ echo '<td><a href="user-edit.php?user_id=' . $val->user_id . '">' . __('Edit') . "</a></td></tr>"; ++ } ++ echo "</table>"; ++ } ++ ++ // New blog user ++ echo "<h3>" . __('Add a new user') . "</h3>"; ++ ?> ++ <p><?php _e('As you type WordPress will offer you a choice of usernames.<br /> Click them to select and hit <em>Update Options</em> to add the user.') ?></p> ++ <table> ++ <tr> ++ <th scope="row"><?php _e('User Login:') ?></th> ++ <td><input type="text" name="newuser" id="newuser" /></td> ++ </tr> ++ <tr> ++ <th scope="row"><?php _e('Role:') ?></th> ++ <td> ++ <select name="new_role" id="new_role"> ++ <?php ++ reset( $editblog_roles ); ++ foreach( $editblog_roles as $role => $role_assoc ){ ++ $selected = ( $role == $editblog_default_role ) ? 'selected="selected"' : ''; ++ echo "<option {$selected} value=\"{$role}\">{$role_assoc['name']}</option>"; ++ } ++ ?> ++ </select> ++ </td> ++ </tr> ++ </table> ++ </div> ++ ++ <div class="wrap"> ++ <strong><?php _e('Misc Blog Actions') ?></strong> ++ <p><?php do_action( 'wpmueditblogaction', $id ); ?></p> ++ </div> ++ ++ <p class="submit"> ++ <input type="submit" name="Submit" value="<?php _e('Update Options »') ?>" /></p> ++ </td> ++ </tr> ++ </table> ++ </form> ++ </div> + <?php ++ break; ++ ++ // List blogs ++ default: ++ $start = isset( $_GET['start'] ) ? intval( $_GET['start'] ) : 0; ++ $num = isset( $_GET['num'] ) ? intval( $_GET['num'] ) : 60; ++ ++ $query = "SELECT * FROM {$wpdb->blogs} WHERE site_id = '{$wpdb->siteid}' "; ++ ++ if( !empty($_GET['s']) ) { ++ $s = trim($_GET['s']); + $query = "SELECT blog_id, {$wpdb->blogs}.domain, {$wpdb->blogs}.path, registered, last_updated ++ FROM {$wpdb->blogs}, {$wpdb->site} ++ WHERE site_id = '{$wpdb->siteid}' ++ AND {$wpdb->blogs}.site_id = {$wpdb->site}.id ++ AND ( {$wpdb->blogs}.domain LIKE '%{$s}%' OR {$wpdb->blogs}.path LIKE '%{$s}%' )"; ++ } elseif( !empty($_GET['blog_id']) ) { + $query = "SELECT * ++ FROM {$wpdb->blogs} ++ WHERE site_id = '{$wpdb->siteid}' ++ AND blog_id = '".intval($_GET['blog_id'])."'"; ++ } elseif( !empty($_GET['ip_address']) ) { ++ $query = "SELECT * ++ FROM {$wpdb->blogs}, {$wpdb->registration_log} ++ WHERE site_id = '{$wpdb->siteid}' ++ AND {$wpdb->blogs}.blog_id = {$wpdb->registration_log}.blog_id ++ AND {$wpdb->registration_log}.IP LIKE ('%".$_GET['ip_address']."%')"; + } ++ ++ if( isset( $_GET['sortby'] ) == false ) { ++ $_GET['sortby'] = 'id'; + } ++ ++ if( $_GET['sortby'] == 'registered' ) { + $query .= ' ORDER BY registered '; ++ } elseif( $_GET['sortby'] == 'id' ) { + $query .= ' ORDER BY ' . $wpdb->blogs . '.blog_id '; ++ } elseif( $_GET['sortby'] == 'lastupdated' ) { + $query .= ' ORDER BY last_updated '; ++ } elseif( $_GET['sortby'] == 'blogname' ) { + $query .= ' ORDER BY domain '; + } ++ ++ $query .= ( $_GET['order'] == 'DESC' ) ? 'DESC' : 'ASC'; ++ ++ if ( $_GET['ip_address'] == '' ) { ++ $query .= " LIMIT " . intval( $start ) . ", " . intval( $num ); + } ++ ++ $blog_list = $wpdb->get_results( $query, ARRAY_A ); ++ ++ $next = ( count( $blog_list ) < $num ) ? false : true; ++ ++ // Pagination ++ $url2 = "order=" . $_GET['order'] . "&sortby=" . $_GET['sortby'] . "&s=" . $_GET['s'] . "&ip_address=" . $_GET['ip_address']; + ++ $blog_navigation = ''; ++ if( $start == 0 ) { ++ $blog_navigation .= __('Previous Blogs'); ++ } elseif( $start <= 30 ) { ++ $blog_navigation .= '<a href="wpmu-blogs.php?start=0&' . $url2 . ' ">' . __('Previous Blogs') . '</a>'; + } else { ++ $blog_navigation .= '<a href="wpmu-blogs.php?start=' . ( $start - $num ) . '&' . $url2 . '">' . __('Previous Blogs') . '</a>'; ++ } ++ if ( $next ) { ++ $blog_navigation .= ' || <a href="wpmu-blogs.php?start=' . ( $start + $num ) . '&' . $url2 . '">' . __('Next Blogs') . '</a>'; ++ } else { ++ $blog_navigation .= ' || ' . __('Next Blogs'); + } ++ ?> ++ <script type="text/javascript"> ++ <!-- ++ var checkflag = "false"; ++ ++ function check_all_rows() { ++ var button1 = document.getElementById('check_all1'); ++ var button2 = document.getElementById('check_all2'); ++ ++ field = document.formlist; ++ if (checkflag == "false") { ++ for (i = 0; i < field.length; i++) { ++ if( field[i].name == 'allblogs[]' ) { ++ field[i].checked = true; ++ } ++ } ++ checkflag = "true"; ++ button1.value = "<?php _e('Uncheck All') ?>"; ++ button2.value = "<?php _e('Uncheck All') ?>"; ++ } else { ++ for (i = 0; i < field.length; i++) { ++ if( field[i].name == 'allblogs[]' ) { ++ field[i].checked = false; ++ } ++ } ++ checkflag = "false"; ++ button1.value = "<?php _e('Check All') ?>"; ++ button2.value = "<?php _e('Check All') ?>" ++ } ++ } ++ // --> ++ </script> ++ <div class="wrap"> ++ <h2><?php _e('Blogs') ?></h2> ++ <div style="float:right; padding:0 20px; margin-top:20px;"> ++ <h4 style="margin:0 0 4px;"><?php _e('Blog Navigation') ?></h4> ++ <?php echo $blog_navigation; ?> ++ </div> ++ ++ <form id="searchform" action="wpmu-blogs.php" method="get"> ++ <input type="hidden" name="action" value="blogs" /> ++ <fieldset> ++ <legend><?php _e('Search blogs by name…') ?></legend> ++ <input type="text" name="s" value="<?php if (isset($_GET['s'])) echo stripslashes(wp_specialchars($_GET['s'], 1)); ?>" size="17" /> ++ </fieldset> ++ ++ <fieldset> ++ <legend><?php _e('by blog ID…') ?></legend> ++ <input type="text" name="blog_id" value="<?php if (isset($_GET['blog_id'])) echo wp_specialchars($_GET['blog_id'], 1); ?>" size="10" /> ++ </fieldset> ++ ++ <fieldset> ++ <legend><?php _e('by IP address…') ?></legend> ++ <input type="text" name="ip_address" value="<?php if (isset($_GET['ip_address'])) echo wp_specialchars($_GET['ip_address'], 1); ?>" size="10" /> ++ </fieldset> ++ <input type="submit" name="submit" id="post-query-submit" value="<?php _e('Search') ?>" class="button" /> ++ </form> + ++ ++ <br style="clear:both;" /> ++ ++ <?php if( isset($_GET['s']) && !empty($_GET['s']) ) : ?> ++ <p><a href="wpmu-users.php?action=users&s=<?php echo stripslashes(wp_specialchars($_GET['s'], 1)) ?>"><?php _e('Search Users:') ?> <strong><?php echo stripslashes(wp_specialchars($_GET['s'], 1)); ?></strong></a></p> ++ <?php endif; ?> ++ ++ <?php ++ // define the columns to display, the syntax is 'internal name' => 'display name' ++ $posts_columns = array( ++ 'id' => __('ID'), ++ 'blogname' => __('Blog Name'), ++ 'lastupdated' => __('Last Updated'), ++ 'registered' => __('Registered'), ++ 'users' => __('Users'), ++ 'plugins' => __('Actions') ++ ); ++ $posts_columns = apply_filters('manage_posts_columns', $posts_columns); + ++ // you can not edit these at the moment ++ $posts_columns['control_view'] = ''; ++ $posts_columns['control_edit'] = ''; ++ $posts_columns['control_backend'] = ''; ++ $posts_columns['control_deactivate']= ''; ++ $posts_columns['control_archive'] = ''; ++ $posts_columns['control_spam'] = ''; ++ $posts_columns['control_delete'] = ''; + ++ $sortby_url = "s=" . $_GET['s'] . "&ip_address=" . $_GET['ip_address']; ++ ?> ++ <form name="formlist" action="wpmu-edit.php?action=allblogs" method="post"> ++ <input style="margin:5px 0;" id="check_all1" class="button" type="button" value="<?php _e('Check All') ?>" onclick="check_all_rows()" /> ++ ++ <table width="100%" cellpadding="3" cellspacing="3" class="widefat"> ++ <thead> ++ <tr> ++ <?php foreach($posts_columns as $column_id => $column_display_name) : ?> ++ <th scope="col"><a href="wpmu-blogs.php?<?php echo $sortby_url ?>&sortby=<?php echo $column_id ?>&<?php if( $_GET['sortby'] == $column_id ) { if( $_GET['order'] == 'DESC' ) { echo "order=ASC&" ; } else { echo "order=DESC&"; } } ?>start=<?php echo $start ?>"><?php echo $column_display_name; ?></a></th> ++ <?php endforeach ?> ++ </tr> ++ </thead> ++ <tbody id="the-list"> ++ <?php ++ if ($blog_list) { ++ $bgcolor = ''; ++ $status_list = array( "archived" => "#fee", "spam" => "#faa", "deleted" => "#f55" ); ++ foreach ($blog_list as $blog) { ++ $class = ('alternate' == $class) ? '' : 'alternate'; ++ reset( $status_list ); ++ ++ $bgcolour = ""; ++ foreach ( $status_list as $status => $col ) { ++ if( get_blog_status( $blog['blog_id'], $status ) == 1 ) { ++ $bgcolour = "style='background: $col'"; ++ } ++ } ++ echo "<tr $bgcolour class='$class'>"; ++ ++ $blogname = ( constant( "VHOST" ) == 'yes' ) ? str_replace('.'.$current_site->domain, '', $blog['domain']) : $blog['path']; + ++ foreach( $posts_columns as $column_name=>$column_display_name ) { ++ switch($column_name) { ++ case 'id': ?> ++ <th scope="row"> ++ <input type='checkbox' id='blog_<?php echo $blog['blog_id'] ?>' name='allblogs[]' value='<?php echo $blog['blog_id'] ?>' /> <label for='blog_<?php echo $blog['blog_id'] ?>'><?php echo $blog['blog_id'] ?></label> ++ </th> ++ <?php ++ break; + ++ case 'blogname': ?> ++ <td valign="top"> ++ <label for='blog_<?php echo $blog['blog_id'] ?>'><?php echo $blogname ?></label> ++ </td> ++ <?php ++ break; + ++ case 'lastupdated': ?> ++ <td valign="top"> ++ <?php echo ( $blog['last_updated'] == '0000-00-00 00:00:00' ) ? __("Never") : mysql2date(__('Y-m-d \<\b\r \/\> g:i:s a'), $blog['last_updated']); ?> ++ </td> ++ <?php ++ break; + ++ case 'registered': ?> ++ <td valign="top"> ++ <?php echo mysql2date(__('Y-m-d \<\b\r \/\> g:i:s a'), $blog['registered']); ?> ++ </td> ++ <?php ++ break; + ++ case 'users': ?> ++ <td valign="top"> ++ <?php ++ $blogusers = get_users_of_blog( $blog['blog_id'] ); ++ if( is_array( $blogusers ) ) { ++ if( $blog['blog_id'] == 1 && count( $blogusers ) > 10 ) { ++ $blogusers = array_slice( $blogusers, 0, 10 ); ++ } ++ foreach ( $blogusers as $key => $val ) { ++ echo '<a href="user-edit.php?user_id=' . $val->user_id . '">' . $val->user_login . '</a> ('.$val->user_email.')<br />'; ++ } ++ } ++ ?> ++ </td> ++ <?php ++ break; + ++ case 'control_view': ?> ++ <td valign="top"> ++ <a href="http://<?php echo $blog['domain']. $blog['path']; ?>" rel="permalink" class="edit"><?php _e('View'); ?></a> ++ </td> ++ <?php ++ break; + ++ case 'control_edit': ?> ++ <td valign="top"> ++ <?php echo "<a href='wpmu-blogs.php?action=editblog&id=".$blog['blog_id']."' class='edit'>" . __('Edit') . "</a>"; ?> ++ </td> ++ <?php ++ break; + ++ case 'control_backend': ++ ?> ++ <td valign="top"> ++ <?php echo "<a href='http://" . $blog['domain'] . $blog['path'] . "wp-admin/' class='edit'>" . __('Backend') . "</a>"; ?> ++ </td> ++ <?php ++ break; + ++ case 'control_spam': ++ if( get_blog_status( $blog['blog_id'], "spam" ) == '1' ) { ?> ++ <td valign="top"> ++ <a class='delete' href="wpmu-edit.php?action=confirm&action2=unspamblog&id=<?php echo $blog['blog_id'] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to unspam the blog %s" ), $blogname ) ) ?>" onclick="return deleteSomething( 'blog', <?php echo $blog['blog_id']; ?>, '<?php echo js_escape(sprintf(__("You are about to mark as not spam this blog '%s'.\n'OK' to delete, 'Cancel' to stop."), $blogname)); ?>' );"><?php _e("Not Spam") ?></a> ++ </td> ++ <?php } else { ?> ++ <td valign='top'> ++ <a class='delete' href="wpmu-edit.php?action=confirm&action2=spamblog&id=<?php echo $blog['blog_id'] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to mark the blog %s as spam" ), $blogname ) ) ?>" onclick="return deleteSomething( 'blog', <?php echo $blog['blog_id']; ?>, '<?php echo js_escape(sprintf(__("You are about to mark as spam this blog '%s'.\n'OK' to delete, 'Cancel' to stop."), $blogname)); ?>' );"><?php _e("Spam") ?></a> ++ </td> ++ <?php } ++ break; + ++ case 'control_deactivate': ++ if( get_blog_status( $blog['blog_id'], "deleted" ) == '1' ) { ?> ++ <td valign="top"> ++ <a class='delete' href="wpmu-edit.php?action=confirm&action2=activateblog&ref=<?php echo urlencode( $_SERVER['REQUEST_URI'] ) ?>&id=<?php echo $blog['blog_id'] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to activate the blog %s" ), $blogname ) ) ?>" onclick="return deleteSomething( 'blog', <?php echo $blog['blog_id']; ?>, '<?php echo js_escape(sprintf(__("You are about to activate this blog '%s'.\n'OK' to delete, 'Cancel' to stop."), $blogname)); ?>' );"><?php _e("Activate") ?></a> ++ </td> ++ <?php } else { ?> ++ <td valign="top"> ++ <a class='delete' href="wpmu-edit.php?action=confirm&action2=deactivateblog&ref=<?php echo urlencode( $_SERVER['REQUEST_URI'] ) ?>&id=<?php echo $blog['blog_id'] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to deactivate the blog %s" ), $blogname ) ) ?>" onclick="return deleteSomething( 'blog', <?php echo $blog['blog_id']; ?>, '<?php echo js_escape(sprintf(__("You are about to deactive this blog '%s'.\n'OK' to delete, 'Cancel' to stop."), $blogname)); ?>' );"><?php _e("Deactivate") ?></a> ++ </td> ++ <?php } ++ break; + ++ case 'control_archive': ++ if( get_blog_status( $blog['blog_id'], "archived" ) == '1' ) { ?> ++ <td valign="top"> ++ <a class='delete' href="wpmu-edit.php?action=confirm&action2=unarchiveblog&id=<?php echo $blog['blog_id'] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to unarchive the blog %s" ), $blogname ) ) ?>" onclick="return deleteSomething( 'blog', <?php echo $blog['blog_id']; ?>, '<?php echo js_escape(sprintf(__("You are about to unarchive this blog '%s'.\n'OK' to delete, 'Cancel' to stop."), $blogname)); ?>' );"><?php _e("Unarchive") ?></a> ++ </td> ++ <?php } else { ?> ++ <td valign="top"> ++ <a class='delete' href="wpmu-edit.php?action=confirm&action2=archiveblog&id=<?php echo $blog['blog_id'] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to archive the blog %s" ), $blogname ) ) ?>" onclick="return deleteSomething( 'blog', <?php echo $blog['blog_id']; ?>, '<?php echo js_escape(sprintf(__("You are about to archive this blog '%s'.\n'OK' to delete, 'Cancel' to stop."), $blogname)); ?>' );"><?php _e("Archive") ?></a> ++ </td> ++ <?php } ++ break; + ++ case 'control_delete': ?> ++ <td valign="top"> ++ <a class='delete' href="wpmu-edit.php?action=confirm&action2=deleteblog&id=<?php echo $blog['blog_id'] ?>&msg=<?php echo urlencode( sprintf( __( "You are about to delete the blog %s" ), $blogname ) ) ?>" onclick="return deleteSomething( 'blog', <?php echo $blog['blog_id']; ?>, '<?php echo js_escape(sprintf(__("You are about to delete this blog '%s'.\n'OK' to delete, 'Cancel' to stop."), $blogname)); ?>' );"><?php _e("Delete") ?></a> ++ </td> ++ <?php break; + ++ case 'plugins': ?> ++ <td valign="top"> ++ <?php do_action( "wpmublogsaction", $blog['blog_id'] ); ?> ++ </td> ++ <?php break; + ++ default: ?> ++ <td valign="top"> ++ <?php do_action('manage_blogs_custom_column', $column_name, $blog['blog_id']); ?> ++ </td> ++ <?php break; ++ } ++ } ++ ?> ++ </tr> ++ <?php ++ } ++ } else { ?> ++ <tr style='background-color: <?php echo $bgcolor; ?>'> ++ <td colspan="8"><?php _e('No blogs found.') ?></td> ++ </tr> + <?php ++ } // end if ($blogs) + ?> ++ </tbody> ++ </table> ++ ++ <div style="float:right; padding:0 20px; margin-top:20px;"> ++ <h4 style="margin:0 0 4px;"><?php _e('Blog Navigation') ?></h4> ++ <?php echo $blog_navigation;?> ++ </div> + ++ <input style="margin:5px 0;" id="check_all2" type="button" class="button" value="<?php _e('Check All') ?>" onclick="check_all_rows()" /> ++ ++ <h3><?php _e('Update selected blogs:') ?></h3> ++ <ul style="list-style:none;"> ++ <li><input type='radio' name='blogfunction' id='delete' value='delete' /> <label for='delete'><?php _e('Delete') ?></label></li> ++ <li><input type='radio' name='blogfunction' id='spam' value='spam' /> <label for='spam'><?php _e('Mark as Spam') ?></label></li> ++ </ul> ++ ++ <p class="submit" style="width: 220px"> ++ <?php wp_nonce_field( "allblogs" ); ?> ++ <input type='hidden' name='redirect' value='<?php echo $_SERVER['REQUEST_URI'] ?>' /> ++ <input type='submit' class="button" value='<?php _e('Apply Changes') ?>' /></p> ++ </form> ++ </div> ++ ++ <div class="wrap"> ++ <h2><?php _e('Add Blog') ?></h2> ++ <form method="post" action="wpmu-edit.php?action=addblog"> ++ <?php wp_nonce_field('add-blog') ?> ++ <table cellpadding="3" cellspacing="3"> ++ <tr> ++ <th style="text-align:center;" scope='row'><?php _e('Blog Address') ?></th> ++ <td> ++ <?php if( constant( "VHOST" ) == 'yes' ) : ?> ++ <input name="blog[domain]" type="text" title="<?php _e('Domain') ?>"/>.<?php echo $current_site->domain;?> ++ <?php else: ++ echo $current_site->domain . $current_site->path ?><input name="blog[domain]" type="text" title="<?php _e('Domain') ?>"/> ++ <?php endif; ?> ++ </td> ++ </tr> ++ <tr><th style="text-align:center;" scope='row'><?php _e('Blog Title') ?></th><td><input name="blog[title]" type="text" size="20" title="<?php _e('Title') ?>"/></td></tr> ++ <tr><th style="text-align:center;" scope='row'><?php _e('Admin Email') ?></th><td><input name="blog[email]" type="text" size="20" title="<?php _e('Email') ?>"/></td></tr> ++ <tr><td colspan='2'><?php _e('A new user will be created if the above email address is not in the database.') ?></td></tr> ++ </table> ++ <input class="button" type="submit" name="go" value="<?php _e('Add Blog') ?>" /> ++ </form> ++ </div> + <?php ++ break; + } // end switch( $action ) + ++ include('admin-footer.php'); ?>
\ No newline at end of file |