Version Description
- Complete rewrite of the plugin making use of custom post types and other best practices. Fresh start version '1' to prevent auto-updates (legacy importer needs to be used to migrate from old versions).
=
Download this release
Release Info
Developer | jolley_small |
Plugin | Download Monitor |
Version | 1.0.0 |
Comparing to | |
See all releases |
Version 1.0.0
- assets/css/admin.css +588 -0
- assets/css/admin.less +523 -0
- assets/css/frontend.css +1 -0
- assets/css/frontend.less +137 -0
- assets/images/ajax-loader.gif +0 -0
- assets/images/cross.png +0 -0
- assets/images/download_count_head.png +0 -0
- assets/images/downloads-icon.gif +0 -0
- assets/images/featured_head.png +0 -0
- assets/images/filetypes/document-code.png +0 -0
- assets/images/filetypes/document-excel.png +0 -0
- assets/images/filetypes/document-film.png +0 -0
- assets/images/filetypes/document-flash-movie.png +0 -0
- assets/images/filetypes/document-illustrator.png +0 -0
- assets/images/filetypes/document-image.png +0 -0
- assets/images/filetypes/document-music.png +0 -0
- assets/images/filetypes/document-pdf.png +0 -0
- assets/images/filetypes/document-photoshop.png +0 -0
- assets/images/filetypes/document-powerpoint.png +0 -0
- assets/images/filetypes/document-text-image.png +0 -0
- assets/images/filetypes/document-text.png +0 -0
- assets/images/filetypes/document-word-text.png +0 -0
- assets/images/filetypes/document-zipper.png +0 -0
- assets/images/filetypes/document.png +0 -0
- assets/images/filetypes/readme.txt +63 -0
- assets/images/folder-horizontal-open.png +0 -0
- assets/images/folder-horizontal.png +0 -0
- assets/images/media-button-download.gif +0 -0
- assets/images/member_head.png +0 -0
- assets/images/menu_icon.png +0 -0
- assets/images/on.png +0 -0
- assets/images/placeholder.png +0 -0
- assets/js/blockui.js +499 -0
- assets/js/blockui.min.js +13 -0
- assets/js/chosen/chosen-sprite.png +0 -0
- assets/js/chosen/chosen-sprite@2x.png +0 -0
- assets/js/chosen/chosen.css +413 -0
- assets/js/chosen/chosen.jquery.js +1090 -0
- assets/js/chosen/chosen.jquery.min.js +10 -0
- assets/js/jqueryFileTree/connectors/jqueryFileTree.php +66 -0
- assets/js/jqueryFileTree/connectors/jqueryFileTreeDir.php +60 -0
- assets/js/jqueryFileTree/images/application.png +0 -0
- assets/js/jqueryFileTree/images/code.png +0 -0
- assets/js/jqueryFileTree/images/css.png +0 -0
- assets/js/jqueryFileTree/images/db.png +0 -0
- assets/js/jqueryFileTree/images/directory.png +0 -0
- assets/js/jqueryFileTree/images/doc.png +0 -0
- assets/js/jqueryFileTree/images/file.png +0 -0
- assets/js/jqueryFileTree/images/film.png +0 -0
- assets/js/jqueryFileTree/images/flash.png +0 -0
- assets/js/jqueryFileTree/images/folder_open.png +0 -0
- assets/js/jqueryFileTree/images/html.png +0 -0
- assets/js/jqueryFileTree/images/java.png +0 -0
- assets/js/jqueryFileTree/images/linux.png +0 -0
- assets/js/jqueryFileTree/images/music.png +0 -0
- assets/js/jqueryFileTree/images/pdf.png +0 -0
- assets/js/jqueryFileTree/images/php.png +0 -0
- assets/js/jqueryFileTree/images/picture.png +0 -0
- assets/js/jqueryFileTree/images/ppt.png +0 -0
- assets/js/jqueryFileTree/images/psd.png +0 -0
- assets/js/jqueryFileTree/images/ruby.png +0 -0
- assets/js/jqueryFileTree/images/script.png +0 -0
- assets/js/jqueryFileTree/images/spinner.gif +0 -0
- assets/js/jqueryFileTree/images/txt.png +0 -0
- assets/js/jqueryFileTree/images/xls.png +0 -0
- assets/js/jqueryFileTree/images/zip.png +0 -0
- assets/js/jqueryFileTree/jqueryFileTree.css +101 -0
- assets/js/jqueryFileTree/jqueryFileTree.js +95 -0
- download-monitor.php +535 -0
- includes/admin/class-dlm-admin-cpt.php +305 -0
- includes/admin/class-dlm-admin-dashboard.php +91 -0
- includes/admin/class-dlm-admin-insert.php +350 -0
- includes/admin/class-dlm-admin-media-browser.php +116 -0
- includes/admin/class-dlm-admin-writepanels.php +480 -0
- includes/admin/class-dlm-admin.php +413 -0
- includes/admin/class-dlm-category-walker.php +48 -0
- includes/admin/class-dlm-logging-list-table.php +171 -0
- includes/admin/html-downloadable-file-version.php +41 -0
- includes/admin/uaparser/CHANGELOG +169 -0
- includes/admin/uaparser/LICENSE +11 -0
- includes/admin/uaparser/README.md +125 -0
- includes/admin/uaparser/lib/json/JSON.php +867 -0
- includes/admin/uaparser/lib/json/jsonwrapper.php +21 -0
- includes/admin/uaparser/lib/spyc-0.5/COPYING +21 -0
- includes/admin/uaparser/lib/spyc-0.5/README +159 -0
- includes/admin/uaparser/lib/spyc-0.5/examples/yaml-dump.php +25 -0
- includes/admin/uaparser/lib/spyc-0.5/examples/yaml-load.php +21 -0
- includes/admin/uaparser/lib/spyc-0.5/spyc.php +1046 -0
- includes/admin/uaparser/lib/spyc-0.5/spyc.yaml +203 -0
- includes/admin/uaparser/lib/spyc-0.5/tests/DumpTest.php +130 -0
- includes/admin/uaparser/lib/spyc-0.5/tests/IndentTest.php +65 -0
- includes/admin/uaparser/lib/spyc-0.5/tests/ParseTest.php +322 -0
- includes/admin/uaparser/lib/spyc-0.5/tests/RoundTripTest.php +61 -0
- includes/admin/uaparser/lib/spyc-0.5/tests/failing1.yaml +2 -0
- includes/admin/uaparser/lib/spyc-0.5/tests/indent_1.yaml +59 -0
- includes/admin/uaparser/lib/spyc-0.5/tests/quotes.yaml +8 -0
- includes/admin/uaparser/log/.gitignore +2 -0
- includes/admin/uaparser/log/README.md +1 -0
- includes/admin/uaparser/resources/regexes.json +1193 -0
- includes/admin/uaparser/uaparser-cli.php +279 -0
- includes/admin/uaparser/uaparser-test.php +104 -0
- includes/admin/uaparser/uaparser.php +303 -0
- includes/class-dlm-ajax-handler.php +137 -0
- includes/class-dlm-download-handler.php +331 -0
- includes/class-dlm-download-version.php +88 -0
- includes/class-dlm-download.php +458 -0
- includes/class-dlm-logging.php +87 -0
- includes/class-dlm-shortcodes.php +324 -0
- includes/widgets/class-dlm-widget-downloads.php +196 -0
- readme.txt +117 -0
- templates/content-download-box.php +28 -0
- templates/content-download-button.php +11 -0
- templates/content-download-filename.php +10 -0
- templates/content-download.php +10 -0
assets/css/admin.css
ADDED
@@ -0,0 +1,588 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Menu */
|
2 |
+
#adminmenu #menu-posts-dlm_download div.wp-menu-image {
|
3 |
+
background: transparent url(../images/menu_icon.png) no-repeat 1px -28px;
|
4 |
+
height: 23px;
|
5 |
+
}
|
6 |
+
#adminmenu #menu-posts-dlm_download.wp-menu-open div.wp-menu-image,
|
7 |
+
#adminmenu #menu-posts-dlm_download:hover div.wp-menu-image {
|
8 |
+
background-position: 1px 0;
|
9 |
+
}
|
10 |
+
#adminmenu #menu-posts-dlm_download img {
|
11 |
+
display: none;
|
12 |
+
}
|
13 |
+
/* Widgets */
|
14 |
+
table.download_chart {
|
15 |
+
width: 100%;
|
16 |
+
}
|
17 |
+
table.download_chart thead {
|
18 |
+
display: none;
|
19 |
+
}
|
20 |
+
table.download_chart td,
|
21 |
+
table.download_chart th {
|
22 |
+
padding: 5px;
|
23 |
+
vertical-align: middle;
|
24 |
+
line-height: 1.5em;
|
25 |
+
}
|
26 |
+
table.download_chart th {
|
27 |
+
text-align: left;
|
28 |
+
font-weight: normal;
|
29 |
+
padding-left: 0;
|
30 |
+
}
|
31 |
+
table.download_chart td:last-child {
|
32 |
+
padding-right: 0;
|
33 |
+
}
|
34 |
+
table.download_chart tr:first-child td,
|
35 |
+
table.download_chart tr:first-child th {
|
36 |
+
padding-top: 0;
|
37 |
+
}
|
38 |
+
table.download_chart tr:last-child td,
|
39 |
+
table.download_chart tr:last-child th {
|
40 |
+
border-bottom: 0;
|
41 |
+
padding-bottom: 0;
|
42 |
+
}
|
43 |
+
table.download_chart span.bar {
|
44 |
+
padding: 0 0 0 1px;
|
45 |
+
height: 1.5em;
|
46 |
+
float: left;
|
47 |
+
margin-right: 5px;
|
48 |
+
-moz-box-sizing: border-box;
|
49 |
+
-webkit-box-sizing: border-box;
|
50 |
+
box-sizing: border-box;
|
51 |
+
-moz-border-radius: 2px;
|
52 |
+
-webkit-border-radius: 2px;
|
53 |
+
border-radius: 2px;
|
54 |
+
bprder: 1px solid ##6e6e6e;
|
55 |
+
background: #6e6e6e;
|
56 |
+
background-image: -webkit-gradient(linear, left bottom, left top, from(#747474), to(#6e6e6e));
|
57 |
+
background-image: -webkit-linear-gradient(bottom, #747474, #6e6e6e);
|
58 |
+
background-image: -moz-linear-gradient(bottom, #747474, #6e6e6e);
|
59 |
+
background-image: -o-linear-gradient(bottom, #747474, #6e6e6e);
|
60 |
+
background-image: linear-gradient(to top, #747474, #6e6e6e);
|
61 |
+
}
|
62 |
+
/* Logs */
|
63 |
+
#dlm_logs .tablenav.top {
|
64 |
+
display: none;
|
65 |
+
}
|
66 |
+
#dlm_logs td {
|
67 |
+
padding: 7px 7px;
|
68 |
+
vertical-align: middle;
|
69 |
+
}
|
70 |
+
#dlm_logs .column-status {
|
71 |
+
width: 4em;
|
72 |
+
}
|
73 |
+
#dlm_logs td.column-status {
|
74 |
+
font-size: 10px;
|
75 |
+
vertical-align: middle;
|
76 |
+
text-align: center;
|
77 |
+
}
|
78 |
+
#dlm_logs td.column-status span {
|
79 |
+
color: #fff;
|
80 |
+
font-weight: normal;
|
81 |
+
-moz-border-radius: 50%;
|
82 |
+
-webkit-border-radius: 50%;
|
83 |
+
border-radius: 50%;
|
84 |
+
height: 16px;
|
85 |
+
line-height: 16px;
|
86 |
+
width: 16px;
|
87 |
+
display: inline-block;
|
88 |
+
}
|
89 |
+
#dlm_logs td.column-status .failed {
|
90 |
+
background-color: #df9d1d;
|
91 |
+
}
|
92 |
+
#dlm_logs td.column-status .redirected {
|
93 |
+
background-color: #74a721;
|
94 |
+
}
|
95 |
+
#dlm_logs td.column-status .completed {
|
96 |
+
background-color: #1c769b;
|
97 |
+
}
|
98 |
+
#dlm_logs td.column-user_ip,
|
99 |
+
#dlm_logs td.column-user_agent {
|
100 |
+
font-family: monospace;
|
101 |
+
font-weight: normal;
|
102 |
+
}
|
103 |
+
#dlm_logs span.description {
|
104 |
+
font-weight: normal;
|
105 |
+
}
|
106 |
+
#dlm_logs .column-download,
|
107 |
+
#dlm_logs .column-file,
|
108 |
+
#dlm_logs .column-user,
|
109 |
+
#dlm_logs .column-user_ua {
|
110 |
+
width: 16% !important;
|
111 |
+
}
|
112 |
+
#dlm_logs .column-user_ip,
|
113 |
+
#dlm_logs .column-date {
|
114 |
+
width: 6% !important;
|
115 |
+
}
|
116 |
+
/* Admin icon */
|
117 |
+
.icon32-posts-dlm_download {
|
118 |
+
background: url(../images/downloads-icon.gif) no-repeat scroll -7px -5px !important;
|
119 |
+
}
|
120 |
+
/* File lists */
|
121 |
+
ul.download_monitor_file_browser {
|
122 |
+
list-style: none outside;
|
123 |
+
margin: 0;
|
124 |
+
border: 1px solid #ddd;
|
125 |
+
-moz-border-radius: 3px;
|
126 |
+
-webkit-border-radius: 3px;
|
127 |
+
border-radius: 3px;
|
128 |
+
background: #f9f9f9;
|
129 |
+
padding: 5px 5px;
|
130 |
+
-moz-box-shadow: inset 0 0 0 1px #fff;
|
131 |
+
-webkit-box-shadow: inset 0 0 0 1px #fff;
|
132 |
+
box-shadow: inset 0 0 0 1px #fff;
|
133 |
+
}
|
134 |
+
ul.download_monitor_file_browser li {
|
135 |
+
padding: 0;
|
136 |
+
margin: 0;
|
137 |
+
}
|
138 |
+
ul.download_monitor_file_browser li a {
|
139 |
+
color: #21759B;
|
140 |
+
display: block;
|
141 |
+
padding: 4px 0 4px 28px;
|
142 |
+
background: #ffffff url(../images/filetype_icons/document.png) no-repeat 4px center;
|
143 |
+
text-decoration: none;
|
144 |
+
}
|
145 |
+
ul.download_monitor_file_browser li a:hover {
|
146 |
+
background-color: #eaf2fa;
|
147 |
+
}
|
148 |
+
ul.download_monitor_file_browser li a.folder {
|
149 |
+
background-image: url(../images/folder-horizontal.png);
|
150 |
+
}
|
151 |
+
ul.download_monitor_file_browser li a.folder_open {
|
152 |
+
background-image: url(../images/folder-horizontal-open.png);
|
153 |
+
}
|
154 |
+
ul.download_monitor_file_browser li a.filetype-html,
|
155 |
+
ul.download_monitor_file_browser li a.filetype-js,
|
156 |
+
ul.download_monitor_file_browser li a.filetype-htm,
|
157 |
+
ul.download_monitor_file_browser li a.filetype-php,
|
158 |
+
ul.download_monitor_file_browser li a.filetype-asp,
|
159 |
+
ul.download_monitor_file_browser li a.filetype-css {
|
160 |
+
background-image: url(../images/filetype_icons/document-code.png);
|
161 |
+
}
|
162 |
+
ul.download_monitor_file_browser li a.filetype-xlsx,
|
163 |
+
ul.download_monitor_file_browser li a.filetype-xlsm,
|
164 |
+
ul.download_monitor_file_browser li a.filetype-xlsb,
|
165 |
+
ul.download_monitor_file_browser li a.filetype-xltx,
|
166 |
+
ul.download_monitor_file_browser li a.filetype-xltm,
|
167 |
+
ul.download_monitor_file_browser li a.filetype-xls,
|
168 |
+
ul.download_monitor_file_browser li a.filetype-xlt {
|
169 |
+
background-image: url(../images/filetype_icons/document-excel.png);
|
170 |
+
}
|
171 |
+
ul.download_monitor_file_browser li a.filetype-mov,
|
172 |
+
ul.download_monitor_file_browser li a.filetype-avi,
|
173 |
+
ul.download_monitor_file_browser li a.filetype-3g2,
|
174 |
+
ul.download_monitor_file_browser li a.filetype-3gp,
|
175 |
+
ul.download_monitor_file_browser li a.filetype-asf,
|
176 |
+
ul.download_monitor_file_browser li a.filetype-asx,
|
177 |
+
ul.download_monitor_file_browser li a.filetype-mp4,
|
178 |
+
ul.download_monitor_file_browser li a.filetype-mpg,
|
179 |
+
ul.download_monitor_file_browser li a.filetype-rm,
|
180 |
+
ul.download_monitor_file_browser li a.filetype-srt,
|
181 |
+
ul.download_monitor_file_browser li a.filetype-vob,
|
182 |
+
ul.download_monitor_file_browser li a.filetype-wmv {
|
183 |
+
background-image: url(../images/filetype_icons/document-film.png);
|
184 |
+
}
|
185 |
+
ul.download_monitor_file_browser li a.filetype-flv,
|
186 |
+
ul.download_monitor_file_browser li a.filetype-swf {
|
187 |
+
background-image: url(../images/filetype_icons/document-flash-movie.png);
|
188 |
+
}
|
189 |
+
ul.download_monitor_file_browser li a.filetype-ai,
|
190 |
+
ul.download_monitor_file_browser li a.filetype-eps,
|
191 |
+
ul.download_monitor_file_browser li a.filetype-ps,
|
192 |
+
ul.download_monitor_file_browser li a.filetype-svg {
|
193 |
+
background-image: url(../images/filetype_icons/document-illustrator.png);
|
194 |
+
}
|
195 |
+
ul.download_monitor_file_browser li a.filetype-bmp,
|
196 |
+
ul.download_monitor_file_browser li a.filetype-dds,
|
197 |
+
ul.download_monitor_file_browser li a.filetype-gif,
|
198 |
+
ul.download_monitor_file_browser li a.filetype-jpg,
|
199 |
+
ul.download_monitor_file_browser li a.filetype-jpeg,
|
200 |
+
ul.download_monitor_file_browser li a.filetype-png,
|
201 |
+
ul.download_monitor_file_browser li a.filetype-pspimage,
|
202 |
+
ul.download_monitor_file_browser li a.filetype-tga,
|
203 |
+
ul.download_monitor_file_browser li a.filetype-thm,
|
204 |
+
ul.download_monitor_file_browser li a.filetype-tif,
|
205 |
+
ul.download_monitor_file_browser li a.filetype-yuv,
|
206 |
+
ul.download_monitor_file_browser li a.filetype-ico {
|
207 |
+
background-image: url(../images/filetype_icons/document-image.png);
|
208 |
+
}
|
209 |
+
ul.download_monitor_file_browser li a.filetype-mp3,
|
210 |
+
ul.download_monitor_file_browser li a.filetype-aif,
|
211 |
+
ul.download_monitor_file_browser li a.filetype-iff,
|
212 |
+
ul.download_monitor_file_browser li a.filetype-m3u,
|
213 |
+
ul.download_monitor_file_browser li a.filetype-m4a,
|
214 |
+
ul.download_monitor_file_browser li a.filetype-mid,
|
215 |
+
ul.download_monitor_file_browser li a.filetype-midi,
|
216 |
+
ul.download_monitor_file_browser li a.filetype-mpa,
|
217 |
+
ul.download_monitor_file_browser li a.filetype-ra,
|
218 |
+
ul.download_monitor_file_browser li a.filetype-wav,
|
219 |
+
ul.download_monitor_file_browser li a.filetype-wma {
|
220 |
+
background-image: url(../images/filetype_icons/document-music.png);
|
221 |
+
}
|
222 |
+
ul.download_monitor_file_browser li a.filetype-pdf {
|
223 |
+
background-image: url(../images/filetype_icons/document-pdf.png);
|
224 |
+
}
|
225 |
+
ul.download_monitor_file_browser li a.filetype-psd {
|
226 |
+
background-image: url(../images/filetype_icons/document-photoshop.png);
|
227 |
+
}
|
228 |
+
ul.download_monitor_file_browser li a.filetype-pps,
|
229 |
+
ul.download_monitor_file_browser li a.filetype-ppt,
|
230 |
+
ul.download_monitor_file_browser li a.filetype-pptx {
|
231 |
+
background-image: url(../images/filetype_icons/document-powerpoint.png);
|
232 |
+
}
|
233 |
+
ul.download_monitor_file_browser li a.filetype-rtf,
|
234 |
+
ul.download_monitor_file_browser li a.filetype-wpd,
|
235 |
+
ul.download_monitor_file_browser li a.filetype-wps,
|
236 |
+
ul.download_monitor_file_browser li a.filetype-odt,
|
237 |
+
ul.download_monitor_file_browser li a.filetype-pages {
|
238 |
+
background-image: url(../images/filetype_icons/document-text-image.png);
|
239 |
+
}
|
240 |
+
ul.download_monitor_file_browser li a.filetype-txt,
|
241 |
+
ul.download_monitor_file_browser li a.filetype-tex,
|
242 |
+
ul.download_monitor_file_browser li a.filetype-wps,
|
243 |
+
ul.download_monitor_file_browser li a.filetype-odt,
|
244 |
+
ul.download_monitor_file_browser li a.filetype-log,
|
245 |
+
ul.download_monitor_file_browser li a.filetype-csv,
|
246 |
+
ul.download_monitor_file_browser li a.filetype-xml {
|
247 |
+
background-image: url(../images/filetype_icons/document-text.png);
|
248 |
+
}
|
249 |
+
ul.download_monitor_file_browser li a.filetype-doc,
|
250 |
+
ul.download_monitor_file_browser li a.filetype-docx {
|
251 |
+
background-image: url(../images/filetype_icons/document-word-text.png);
|
252 |
+
}
|
253 |
+
ul.download_monitor_file_browser li a.filetype-7z,
|
254 |
+
ul.download_monitor_file_browser li a.filetype-zip,
|
255 |
+
ul.download_monitor_file_browser li a.filetype-rar,
|
256 |
+
ul.download_monitor_file_browser li a.filetype-zipx,
|
257 |
+
ul.download_monitor_file_browser li a.filetype-sit,
|
258 |
+
ul.download_monitor_file_browser li a.filetype-sitx,
|
259 |
+
ul.download_monitor_file_browser li a.filetype-gz,
|
260 |
+
ul.download_monitor_file_browser li a.filetype-tax-gz {
|
261 |
+
background-image: url(../images/filetype_icons/document-zipper.png);
|
262 |
+
}
|
263 |
+
ul.download_monitor_file_browser li.nofiles {
|
264 |
+
color: #999;
|
265 |
+
font-style: italic;
|
266 |
+
padding: 4px 0;
|
267 |
+
}
|
268 |
+
ul.download_monitor_file_browser li ul {
|
269 |
+
list-style: none outside;
|
270 |
+
margin: 0;
|
271 |
+
padding: 0 0 0 28px;
|
272 |
+
}
|
273 |
+
ul.download_monitor_file_browser li ul.loading {
|
274 |
+
background: url(../images/ajax-loader.gif) no-repeat 24px 0;
|
275 |
+
height: 32px;
|
276 |
+
}
|
277 |
+
/* Download list */
|
278 |
+
table.wp-list-table .column-thumb {
|
279 |
+
width: 52px;
|
280 |
+
text-align: center;
|
281 |
+
white-space: nowrap;
|
282 |
+
}
|
283 |
+
table.wp-list-table .column-dlm_download_cat,
|
284 |
+
table.wp-list-table .column-dlm_download_tag,
|
285 |
+
table.wp-list-table .column-file {
|
286 |
+
width: 11% !important;
|
287 |
+
}
|
288 |
+
table.wp-list-table .column-id,
|
289 |
+
table.wp-list-table .column-version {
|
290 |
+
width: 6%;
|
291 |
+
}
|
292 |
+
table.wp-list-table td.column-members_only,
|
293 |
+
table.wp-list-table td.column-featured {
|
294 |
+
width: 46px;
|
295 |
+
text-align: left;
|
296 |
+
padding-left: 11px;
|
297 |
+
}
|
298 |
+
table.wp-list-table td.column-download_count {
|
299 |
+
width: 6%;
|
300 |
+
text-align: left;
|
301 |
+
padding-left: 11px;
|
302 |
+
}
|
303 |
+
table.wp-list-table th.column-members_only,
|
304 |
+
table.wp-list-table th.column-featured {
|
305 |
+
width: 46px;
|
306 |
+
}
|
307 |
+
table.wp-list-table th.column-members_only img,
|
308 |
+
table.wp-list-table th.column-featured img {
|
309 |
+
padding-top: 3px !important;
|
310 |
+
}
|
311 |
+
table.wp-list-table th.column-download_count {
|
312 |
+
width: 6%;
|
313 |
+
}
|
314 |
+
table.wp-list-table th.column-download_count img {
|
315 |
+
padding-top: 3px !important;
|
316 |
+
}
|
317 |
+
table.wp-list-table img {
|
318 |
+
margin: 1px 2px;
|
319 |
+
}
|
320 |
+
table.wp-list-table .column-thumb img {
|
321 |
+
padding: 2px;
|
322 |
+
margin: 0;
|
323 |
+
border: 1px solid #dfdfdf;
|
324 |
+
vertical-align: middle;
|
325 |
+
width: 32px;
|
326 |
+
height: 32px;
|
327 |
+
}
|
328 |
+
table.wp-list-table span.na {
|
329 |
+
color: #999;
|
330 |
+
}
|
331 |
+
/* Meta boxes */
|
332 |
+
#download-monitor-file .inside {
|
333 |
+
padding: 0;
|
334 |
+
margin: 0;
|
335 |
+
}
|
336 |
+
#download-monitor-file .dlm-metaboxes-wrapper .expand_all,
|
337 |
+
#download-monitor-file .dlm-metaboxes-wrapper .close_all {
|
338 |
+
float: right;
|
339 |
+
margin-left: 9px;
|
340 |
+
line-height: 22px;
|
341 |
+
}
|
342 |
+
#download-monitor-file .dlm-metaboxes-wrapper .expand_all {
|
343 |
+
padding-left: 14px;
|
344 |
+
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAI0lEQVQYV2PcvXv3fwY8gJEoBa6urozYDAFpBpswGBTg8yYA3kYtiYVhDhIAAAAASUVORK5CYII=) no-repeat left;
|
345 |
+
}
|
346 |
+
#download-monitor-file .dlm-metaboxes-wrapper .close_all {
|
347 |
+
padding-left: 14px;
|
348 |
+
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAHUlEQVQYV2NkIAAYd+/e/R+fGsIKCFpBUAHt3QAASf0MyQbFJwoAAAAASUVORK5CYII=) no-repeat left;
|
349 |
+
}
|
350 |
+
#download-monitor-file .dlm-metaboxes-wrapper p.toolbar {
|
351 |
+
margin: 0 !important;
|
352 |
+
border-top: 1px solid white;
|
353 |
+
border-bottom: 1px solid #DFDFDF;
|
354 |
+
padding: 7px 12px !important;
|
355 |
+
overflow: hidden;
|
356 |
+
zoom: 1;
|
357 |
+
}
|
358 |
+
#download-monitor-file .dlm-metaboxes-wrapper p.toolbar a.button {
|
359 |
+
float: left;
|
360 |
+
margin: 0;
|
361 |
+
}
|
362 |
+
#download-monitor-file .dlm-metaboxes-wrapper select.attribute_taxonomy,
|
363 |
+
#download-monitor-file .dlm-metaboxes-wrapper button.add_attribute,
|
364 |
+
#download-monitor-file .dlm-metaboxes-wrapper button.add_variable_attribute,
|
365 |
+
#download-monitor-file .dlm-metaboxes-wrapper .fr {
|
366 |
+
float: right;
|
367 |
+
margin: 0 0 0 6px;
|
368 |
+
}
|
369 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metaboxes {
|
370 |
+
padding: 0 12px 0;
|
371 |
+
}
|
372 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox-sortable-placeholder {
|
373 |
+
border-color: #bbb;
|
374 |
+
background-color: #f5f5f5;
|
375 |
+
margin: 9px 0;
|
376 |
+
border-width: 1px;
|
377 |
+
border-style: dashed;
|
378 |
+
}
|
379 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox {
|
380 |
+
background: #ececec;
|
381 |
+
border: 1px solid #ececec;
|
382 |
+
margin: 9px 0 !important;
|
383 |
+
}
|
384 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox h3 {
|
385 |
+
margin: 0 !important;
|
386 |
+
padding: 6px !important;
|
387 |
+
font-size: 1em !important;
|
388 |
+
overflow: hidden;
|
389 |
+
zoom: 1;
|
390 |
+
cursor: move;
|
391 |
+
}
|
392 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox h3 button {
|
393 |
+
float: right;
|
394 |
+
}
|
395 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox h3 strong {
|
396 |
+
font-weight: normal;
|
397 |
+
line-height: 24px;
|
398 |
+
}
|
399 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox h3 select {
|
400 |
+
font-family: sans-serif;
|
401 |
+
}
|
402 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox h3 .handlediv {
|
403 |
+
background-position: 6px 5px !important;
|
404 |
+
display: none;
|
405 |
+
height: 24px;
|
406 |
+
}
|
407 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox:hover h3 .handlediv {
|
408 |
+
display: block;
|
409 |
+
}
|
410 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table {
|
411 |
+
width: 100%;
|
412 |
+
position: relative;
|
413 |
+
background: #fff;
|
414 |
+
padding: 3px;
|
415 |
+
}
|
416 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td {
|
417 |
+
text-align: left;
|
418 |
+
padding: 6px 6px;
|
419 |
+
vertical-align: top;
|
420 |
+
border: 0;
|
421 |
+
line-height: 26px;
|
422 |
+
}
|
423 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td label {
|
424 |
+
text-align: left;
|
425 |
+
display: block;
|
426 |
+
line-height: 21px;
|
427 |
+
}
|
428 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td input {
|
429 |
+
float: left;
|
430 |
+
min-width: 200px;
|
431 |
+
}
|
432 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td input,
|
433 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td textarea {
|
434 |
+
width: 100%;
|
435 |
+
margin: 0;
|
436 |
+
display: block;
|
437 |
+
font-size: 14px;
|
438 |
+
padding: 4px;
|
439 |
+
color: #555;
|
440 |
+
}
|
441 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td textarea {
|
442 |
+
height: 7.5em;
|
443 |
+
}
|
444 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td select {
|
445 |
+
width: 100%;
|
446 |
+
}
|
447 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td input.short {
|
448 |
+
width: 200px;
|
449 |
+
}
|
450 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td input.checkbox {
|
451 |
+
width: auto;
|
452 |
+
min-width: inherit;
|
453 |
+
vertical-align: middle;
|
454 |
+
display: inline;
|
455 |
+
float: none;
|
456 |
+
}
|
457 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td input.date-picker-field {
|
458 |
+
width: 50%;
|
459 |
+
min-width: inherit;
|
460 |
+
float: none;
|
461 |
+
display: inline;
|
462 |
+
}
|
463 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td input.minute,
|
464 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td input.hour {
|
465 |
+
width: 2em;
|
466 |
+
min-width: inherit;
|
467 |
+
float: none;
|
468 |
+
display: inline;
|
469 |
+
}
|
470 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table td.attribute_name {
|
471 |
+
width: 200px;
|
472 |
+
}
|
473 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table .plus,
|
474 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table .minus {
|
475 |
+
margin-top: 6px;
|
476 |
+
}
|
477 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table .fl {
|
478 |
+
float: left;
|
479 |
+
}
|
480 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox table .fr {
|
481 |
+
float: right;
|
482 |
+
}
|
483 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox:first-child {
|
484 |
+
/* main file */
|
485 |
+
|
486 |
+
}
|
487 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm-metabox:first-child h3 {
|
488 |
+
background: #EAF2FA;
|
489 |
+
background-image: linear-gradient(bottom, #dae6f2 0%, #eaf2fa 100%);
|
490 |
+
background-image: -o-linear-gradient(bottom, #dae6f2 0%, #eaf2fa 100%);
|
491 |
+
background-image: -moz-linear-gradient(bottom, #dae6f2 0%, #eaf2fa 100%);
|
492 |
+
background-image: -webkit-linear-gradient(bottom, #dae6f2 0%, #eaf2fa 100%);
|
493 |
+
background-image: -ms-linear-gradient(bottom, #dae6f2 0%, #eaf2fa 100%);
|
494 |
+
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #dae6f2), color-stop(1, #eaf2fa));
|
495 |
+
border-color: #d3deea;
|
496 |
+
color: #21759B;
|
497 |
+
}
|
498 |
+
#download-monitor-file .dlm-metaboxes-wrapper .plus {
|
499 |
+
padding-left: 20px;
|
500 |
+
background: #fefefe url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAARklEQVQYGWP8//8/AzGACV3Rnj17/oMwujiGQnQFMD7RChlBbsRmFcwkEO3i4sJImonIumGmg0xBFifaRKIVgj2DbAUuNgCfThpracSKqwAAAABJRU5ErkJggg==) no-repeat 7px 5px;
|
501 |
+
}
|
502 |
+
#download-monitor-file .dlm-metaboxes-wrapper .minus {
|
503 |
+
padding-left: 20px;
|
504 |
+
background: #fefefe url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAKUlEQVQYlWP8//8/Az7AhFeWGAUsDAwMDHv27MFqj4uLCyNBExhp70gAohwKC5KJ+HQAAAAASUVORK5CYII=) no-repeat 7px 6px;
|
505 |
+
}
|
506 |
+
#download-monitor-file .dlm-metaboxes-wrapper .dlm_upload_file {
|
507 |
+
padding-left: 20px;
|
508 |
+
background: #fefefe url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAMklEQVQYV2NkQAK7d+/+D+K6uroywoThDJgkTAKmCKwAXRJZESMuSQwrkE3C6gbaKQAAYS4fOXZlROQAAAAASUVORK5CYII=) no-repeat 7px 5px;
|
509 |
+
}
|
510 |
+
#download-monitor-file .dlm-metaboxes-wrapper .browse_for_file {
|
511 |
+
padding-left: 20px;
|
512 |
+
background: #fefefe url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAK0lEQVQYV2NkIAAYd+/e/R+mxtXVlRFdPYoCbIaBFWDTCVIMkqOXAnw+BQCbpycpLX4gIQAAAABJRU5ErkJggg==) no-repeat 7px 5px;
|
513 |
+
}
|
514 |
+
/* Writepanel forms */
|
515 |
+
#download-monitor-options .inside {
|
516 |
+
padding: 0;
|
517 |
+
margin: 0;
|
518 |
+
}
|
519 |
+
#download-monitor-options .form-field-checkbox label {
|
520 |
+
display: inline;
|
521 |
+
padding: 0 0 4px;
|
522 |
+
}
|
523 |
+
#download-monitor-options .form-field-checkbox input {
|
524 |
+
display: inline;
|
525 |
+
width: auto;
|
526 |
+
vertical-align: middle;
|
527 |
+
}
|
528 |
+
#download-monitor-options .form-field-checkbox .description {
|
529 |
+
padding: 4px 0 0 0;
|
530 |
+
display: block;
|
531 |
+
}
|
532 |
+
#download-monitor-options .access_permissions {
|
533 |
+
margin: 0 !important;
|
534 |
+
border-top: 1px solid white;
|
535 |
+
border-bottom: 1px solid #DFDFDF;
|
536 |
+
padding: 7px 12px !important;
|
537 |
+
overflow: hidden;
|
538 |
+
zoom: 1;
|
539 |
+
}
|
540 |
+
#download-monitor-options .access_permissions h4 {
|
541 |
+
margin-bottom: .5em;
|
542 |
+
margin: 0 0 .5em;
|
543 |
+
}
|
544 |
+
#download-monitor-options .access_permissions ul {
|
545 |
+
background: #fff;
|
546 |
+
border: 1px solid #dfdfdf;
|
547 |
+
height: 110px;
|
548 |
+
overflow: auto;
|
549 |
+
padding: .5em .9em;
|
550 |
+
margin: 0;
|
551 |
+
}
|
552 |
+
#download-monitor-options p {
|
553 |
+
margin: 0 !important;
|
554 |
+
border-top: 1px solid white;
|
555 |
+
border-bottom: 1px solid #DFDFDF;
|
556 |
+
padding: 7px 12px !important;
|
557 |
+
overflow: hidden;
|
558 |
+
zoom: 1;
|
559 |
+
}
|
560 |
+
#insert-download {
|
561 |
+
padding: 20px 20px;
|
562 |
+
}
|
563 |
+
#insert-download .updated,
|
564 |
+
#insert-download .error {
|
565 |
+
margin-left: 0;
|
566 |
+
margin-right: 0;
|
567 |
+
}
|
568 |
+
#insert-download h2 {
|
569 |
+
margin-top: 0;
|
570 |
+
}
|
571 |
+
#insert-download label {
|
572 |
+
margin: 0 0 .25em 0;
|
573 |
+
display: block;
|
574 |
+
font-size: 1.1em;
|
575 |
+
}
|
576 |
+
#insert-download span.description {
|
577 |
+
display: block;
|
578 |
+
}
|
579 |
+
#insert-download select.input,
|
580 |
+
#insert-download input.input {
|
581 |
+
margin: 0 0 .25em 0;
|
582 |
+
display: block;
|
583 |
+
width: 100%;
|
584 |
+
font-size: 1.1em;
|
585 |
+
}
|
586 |
+
#insert-download .add_link {
|
587 |
+
float: right;
|
588 |
+
}
|
assets/css/admin.less
ADDED
@@ -0,0 +1,523 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Menu */
|
2 |
+
#adminmenu {
|
3 |
+
#menu-posts-dlm_download {
|
4 |
+
div.wp-menu-image {
|
5 |
+
background: transparent url(../images/menu_icon.png) no-repeat 1px -28px;
|
6 |
+
height: 23px;
|
7 |
+
}
|
8 |
+
&.wp-menu-open div.wp-menu-image, &:hover div.wp-menu-image {
|
9 |
+
background-position: 1px 0;
|
10 |
+
}
|
11 |
+
img {
|
12 |
+
display: none;
|
13 |
+
}
|
14 |
+
}
|
15 |
+
}
|
16 |
+
|
17 |
+
/* Widgets */
|
18 |
+
table.download_chart {
|
19 |
+
width: 100%;
|
20 |
+
thead {
|
21 |
+
display: none;
|
22 |
+
}
|
23 |
+
td, th {
|
24 |
+
padding: 5px;
|
25 |
+
vertical-align: middle;
|
26 |
+
line-height: 1.5em;
|
27 |
+
}
|
28 |
+
th {
|
29 |
+
text-align: left;
|
30 |
+
font-weight: normal;
|
31 |
+
padding-left: 0;
|
32 |
+
}
|
33 |
+
td:last-child {
|
34 |
+
padding-right: 0;
|
35 |
+
}
|
36 |
+
tr:first-child {
|
37 |
+
td, th {
|
38 |
+
padding-top: 0;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
tr:last-child {
|
42 |
+
td, th {
|
43 |
+
border-bottom: 0;
|
44 |
+
padding-bottom: 0;
|
45 |
+
}
|
46 |
+
}
|
47 |
+
span.bar {
|
48 |
+
padding: 0 0 0 1px;
|
49 |
+
height: 1.5em;
|
50 |
+
float: left;
|
51 |
+
margin-right: 5px;
|
52 |
+
-moz-box-sizing: border-box;
|
53 |
+
-webkit-box-sizing: border-box;
|
54 |
+
box-sizing: border-box;
|
55 |
+
-moz-border-radius: 2px;
|
56 |
+
-webkit-border-radius: 2px;
|
57 |
+
border-radius: 2px;
|
58 |
+
bprder:1px solid ##6e6e6e;
|
59 |
+
background:#6e6e6e;
|
60 |
+
background-image:-webkit-gradient(linear,left bottom,left top,from(#747474),to(#6e6e6e));
|
61 |
+
background-image:-webkit-linear-gradient(bottom,#747474,#6e6e6e);
|
62 |
+
background-image:-moz-linear-gradient(bottom,#747474,#6e6e6e);
|
63 |
+
background-image:-o-linear-gradient(bottom,#747474,#6e6e6e);
|
64 |
+
background-image:linear-gradient(to top,#747474,#6e6e6e);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
/* Logs */
|
69 |
+
#dlm_logs {
|
70 |
+
.tablenav.top {
|
71 |
+
display: none;
|
72 |
+
}
|
73 |
+
td {
|
74 |
+
padding: 7px 7px;
|
75 |
+
vertical-align: middle;
|
76 |
+
}
|
77 |
+
.column-status {
|
78 |
+
width: 4em;
|
79 |
+
}
|
80 |
+
td.column-status {
|
81 |
+
font-size: 10px;
|
82 |
+
vertical-align: middle;
|
83 |
+
text-align: center;
|
84 |
+
span {
|
85 |
+
color: #fff;
|
86 |
+
font-weight: normal;
|
87 |
+
-moz-border-radius: 50%;
|
88 |
+
-webkit-border-radius: 50%;
|
89 |
+
border-radius: 50%;
|
90 |
+
height: 16px;
|
91 |
+
line-height: 16px;
|
92 |
+
width: 16px;
|
93 |
+
display: inline-block;
|
94 |
+
}
|
95 |
+
.failed {
|
96 |
+
background-color: #df9d1d;
|
97 |
+
}
|
98 |
+
.redirected {
|
99 |
+
background-color: #74a721;
|
100 |
+
}
|
101 |
+
.completed {
|
102 |
+
background-color: #1c769b;
|
103 |
+
}
|
104 |
+
}
|
105 |
+
td.column-user_ip, td.column-user_agent {
|
106 |
+
font-family: monospace;
|
107 |
+
font-weight: normal;
|
108 |
+
}
|
109 |
+
span.description {
|
110 |
+
font-weight: normal;
|
111 |
+
}
|
112 |
+
.column-download, .column-file, .column-user, .column-user_ua {
|
113 |
+
width: 16% !important;
|
114 |
+
}
|
115 |
+
.column-user_ip, .column-date {
|
116 |
+
width: 6% !important;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
/* Admin icon */
|
121 |
+
.icon32-posts-dlm_download {
|
122 |
+
background: url(../images/downloads-icon.gif) no-repeat scroll -7px -5px !important;
|
123 |
+
}
|
124 |
+
|
125 |
+
/* File lists */
|
126 |
+
ul.download_monitor_file_browser {
|
127 |
+
list-style: none outside;
|
128 |
+
margin: 0;
|
129 |
+
border: 1px solid #ddd;
|
130 |
+
-moz-border-radius: 3px;
|
131 |
+
-webkit-border-radius: 3px;
|
132 |
+
border-radius: 3px;
|
133 |
+
background: #f9f9f9;
|
134 |
+
padding: 5px 5px;
|
135 |
+
-moz-box-shadow: inset 0 0 0 1px #fff;
|
136 |
+
-webkit-box-shadow: inset 0 0 0 1px #fff;
|
137 |
+
box-shadow: inset 0 0 0 1px #fff;
|
138 |
+
|
139 |
+
li {
|
140 |
+
padding: 0;
|
141 |
+
margin: 0;
|
142 |
+
a {
|
143 |
+
color: #21759B;
|
144 |
+
display: block;
|
145 |
+
padding: 4px 0 4px 28px;
|
146 |
+
background: #fff url(../images/filetype_icons/document.png) no-repeat 4px center;
|
147 |
+
text-decoration: none;
|
148 |
+
|
149 |
+
&:hover {
|
150 |
+
background-color: #eaf2fa;
|
151 |
+
}
|
152 |
+
|
153 |
+
&.folder { background-image: url(../images/folder-horizontal.png); }
|
154 |
+
|
155 |
+
&.folder_open { background-image: url(../images/folder-horizontal-open.png); }
|
156 |
+
|
157 |
+
&.filetype-html, &.filetype-js, &.filetype-htm, &.filetype-php, &.filetype-asp, &.filetype-css { background-image: url(../images/filetype_icons/document-code.png); }
|
158 |
+
|
159 |
+
&.filetype-xlsx, &.filetype-xlsm, &.filetype-xlsb, &.filetype-xltx, &.filetype-xltm, &.filetype-xls, &.filetype-xlt { background-image: url(../images/filetype_icons/document-excel.png); }
|
160 |
+
|
161 |
+
&.filetype-mov, &.filetype-avi, &.filetype-3g2, &.filetype-3gp, &.filetype-asf, &.filetype-asx, &.filetype-mp4, &.filetype-mpg, &.filetype-rm, &.filetype-srt, &.filetype-vob, &.filetype-wmv { background-image: url(../images/filetype_icons/document-film.png); }
|
162 |
+
|
163 |
+
&.filetype-flv, &.filetype-swf { background-image: url(../images/filetype_icons/document-flash-movie.png); }
|
164 |
+
|
165 |
+
&.filetype-ai, &.filetype-eps, &.filetype-ps, &.filetype-svg { background-image: url(../images/filetype_icons/document-illustrator.png); }
|
166 |
+
|
167 |
+
&.filetype-bmp, &.filetype-dds, &.filetype-gif, &.filetype-jpg, &.filetype-jpeg, &.filetype-png, &.filetype-pspimage, &.filetype-tga, &.filetype-thm, &.filetype-tif, &.filetype-yuv, &.filetype-ico { background-image: url(../images/filetype_icons/document-image.png); }
|
168 |
+
|
169 |
+
&.filetype-mp3, &.filetype-aif, &.filetype-iff, &.filetype-m3u, &.filetype-m4a, &.filetype-mid, &.filetype-midi, &.filetype-mpa, &.filetype-ra, &.filetype-wav, &.filetype-wma { background-image: url(../images/filetype_icons/document-music.png); }
|
170 |
+
|
171 |
+
&.filetype-pdf { background-image: url(../images/filetype_icons/document-pdf.png); }
|
172 |
+
|
173 |
+
&.filetype-psd { background-image: url(../images/filetype_icons/document-photoshop.png); }
|
174 |
+
|
175 |
+
&.filetype-pps, &.filetype-ppt, &.filetype-pptx { background-image: url(../images/filetype_icons/document-powerpoint.png); }
|
176 |
+
|
177 |
+
&.filetype-rtf, &.filetype-wpd, &.filetype-wps, &.filetype-odt, &.filetype-pages { background-image: url(../images/filetype_icons/document-text-image.png); }
|
178 |
+
|
179 |
+
&.filetype-txt, &.filetype-tex, &.filetype-wps, &.filetype-odt, &.filetype-log, &.filetype-csv, &.filetype-xml { background-image: url(../images/filetype_icons/document-text.png); }
|
180 |
+
|
181 |
+
&.filetype-doc, &.filetype-docx { background-image: url(../images/filetype_icons/document-word-text.png); }
|
182 |
+
|
183 |
+
&.filetype-7z, &.filetype-zip, &.filetype-rar, &.filetype-zipx, &.filetype-sit, &.filetype-sitx, &.filetype-gz, &.filetype-tax-gz { background-image: url(../images/filetype_icons/document-zipper.png); }
|
184 |
+
}
|
185 |
+
|
186 |
+
&.nofiles {
|
187 |
+
color: #999;
|
188 |
+
font-style: italic;
|
189 |
+
padding: 4px 0;
|
190 |
+
}
|
191 |
+
|
192 |
+
ul {
|
193 |
+
list-style: none outside;
|
194 |
+
margin: 0;
|
195 |
+
padding: 0 0 0 28px;
|
196 |
+
|
197 |
+
&.loading {
|
198 |
+
background: url(../images/ajax-loader.gif) no-repeat 24px 0;
|
199 |
+
height: 32px;
|
200 |
+
}
|
201 |
+
}
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
/* Download list */
|
206 |
+
table.wp-list-table {
|
207 |
+
.column-thumb {
|
208 |
+
width: 52px;
|
209 |
+
text-align: center;
|
210 |
+
white-space: nowrap
|
211 |
+
}
|
212 |
+
.column-dlm_download_cat, .column-dlm_download_tag, .column-file {
|
213 |
+
width: 11% !important;
|
214 |
+
}
|
215 |
+
.column-id, .column-version {
|
216 |
+
width: 6%;
|
217 |
+
}
|
218 |
+
td.column-members_only, td.column-featured {
|
219 |
+
width: 46px;
|
220 |
+
text-align: left;
|
221 |
+
padding-left: 11px;
|
222 |
+
}
|
223 |
+
td.column-download_count {
|
224 |
+
width: 6%;
|
225 |
+
text-align: left;
|
226 |
+
padding-left: 11px;
|
227 |
+
}
|
228 |
+
th.column-members_only, th.column-featured {
|
229 |
+
width: 46px;
|
230 |
+
img {
|
231 |
+
padding-top: 3px !important;
|
232 |
+
}
|
233 |
+
}
|
234 |
+
th.column-download_count {
|
235 |
+
width: 6%;
|
236 |
+
img {
|
237 |
+
padding-top: 3px !important;
|
238 |
+
}
|
239 |
+
}
|
240 |
+
img {
|
241 |
+
margin: 1px 2px;
|
242 |
+
}
|
243 |
+
.column-thumb img {
|
244 |
+
padding: 2px;
|
245 |
+
margin: 0;
|
246 |
+
border: 1px solid #dfdfdf;
|
247 |
+
vertical-align: middle;
|
248 |
+
width: 32px;
|
249 |
+
height: 32px;
|
250 |
+
}
|
251 |
+
span.na {
|
252 |
+
color: #999;
|
253 |
+
}
|
254 |
+
}
|
255 |
+
|
256 |
+
/* Meta boxes */
|
257 |
+
#download-monitor-file {
|
258 |
+
.inside {
|
259 |
+
padding: 0;
|
260 |
+
margin: 0;
|
261 |
+
}
|
262 |
+
.dlm-metaboxes-wrapper {
|
263 |
+
.expand_all, .close_all {
|
264 |
+
float: right;
|
265 |
+
margin-left: 9px;
|
266 |
+
line-height: 22px;
|
267 |
+
}
|
268 |
+
.expand_all {
|
269 |
+
padding-left: 14px;
|
270 |
+
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAI0lEQVQYV2PcvXv3fwY8gJEoBa6urozYDAFpBpswGBTg8yYA3kYtiYVhDhIAAAAASUVORK5CYII=) no-repeat left;
|
271 |
+
}
|
272 |
+
.close_all {
|
273 |
+
padding-left: 14px;
|
274 |
+
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAHUlEQVQYV2NkIAAYd+/e/R+fGsIKCFpBUAHt3QAASf0MyQbFJwoAAAAASUVORK5CYII=) no-repeat left;
|
275 |
+
}
|
276 |
+
p.toolbar {
|
277 |
+
margin: 0 !important;
|
278 |
+
border-top: 1px solid white;
|
279 |
+
border-bottom: 1px solid #DFDFDF;
|
280 |
+
padding: 7px 12px !important;
|
281 |
+
overflow: hidden;
|
282 |
+
zoom: 1;
|
283 |
+
|
284 |
+
a.button {
|
285 |
+
float: left;
|
286 |
+
margin: 0;
|
287 |
+
}
|
288 |
+
}
|
289 |
+
select.attribute_taxonomy, button.add_attribute, button.add_variable_attribute, .fr {
|
290 |
+
float: right;
|
291 |
+
margin: 0 0 0 6px;
|
292 |
+
}
|
293 |
+
.dlm-metaboxes {
|
294 |
+
padding: 0 12px 0;
|
295 |
+
}
|
296 |
+
.dlm-metabox-sortable-placeholder {
|
297 |
+
border-color:#bbb;
|
298 |
+
background-color:#f5f5f5;
|
299 |
+
margin: 9px 0;
|
300 |
+
border-width:1px;
|
301 |
+
border-style:dashed;
|
302 |
+
}
|
303 |
+
.dlm-metabox {
|
304 |
+
background: #ececec;
|
305 |
+
border: 1px solid #ececec;
|
306 |
+
margin: 9px 0 !important;
|
307 |
+
h3 {
|
308 |
+
margin: 0 !important;
|
309 |
+
padding: 6px !important;
|
310 |
+
font-size: 1em !important;
|
311 |
+
overflow: hidden;
|
312 |
+
zoom: 1;
|
313 |
+
cursor: move;
|
314 |
+
button {
|
315 |
+
float: right;
|
316 |
+
}
|
317 |
+
strong {
|
318 |
+
font-weight: normal;
|
319 |
+
line-height: 24px;
|
320 |
+
}
|
321 |
+
select {
|
322 |
+
font-family: sans-serif;
|
323 |
+
}
|
324 |
+
.handlediv {
|
325 |
+
background-position: 6px 5px !important;
|
326 |
+
display: none;
|
327 |
+
height: 24px;
|
328 |
+
}
|
329 |
+
}
|
330 |
+
&:hover h3 .handlediv {
|
331 |
+
display: block;
|
332 |
+
}
|
333 |
+
table {
|
334 |
+
width: 100%;
|
335 |
+
position: relative;
|
336 |
+
background: #fff;
|
337 |
+
padding: 3px;
|
338 |
+
td {
|
339 |
+
text-align: left;
|
340 |
+
padding: 6px 6px;
|
341 |
+
vertical-align: top;
|
342 |
+
border: 0;
|
343 |
+
line-height: 26px;
|
344 |
+
label {
|
345 |
+
text-align: left;
|
346 |
+
display: block;
|
347 |
+
line-height: 21px;
|
348 |
+
}
|
349 |
+
input {
|
350 |
+
float: left;
|
351 |
+
min-width: 200px;
|
352 |
+
}
|
353 |
+
input, textarea {
|
354 |
+
width: 100%;
|
355 |
+
margin: 0;
|
356 |
+
display: block;
|
357 |
+
font-size: 14px;
|
358 |
+
padding: 4px;
|
359 |
+
color: #555;
|
360 |
+
}
|
361 |
+
textarea {
|
362 |
+
height: 7.5em;
|
363 |
+
}
|
364 |
+
select {
|
365 |
+
width: 100%;
|
366 |
+
}
|
367 |
+
input.short {
|
368 |
+
width: 200px;
|
369 |
+
}
|
370 |
+
input.checkbox {
|
371 |
+
width: auto;
|
372 |
+
min-width: inherit;
|
373 |
+
vertical-align: middle;
|
374 |
+
display: inline;
|
375 |
+
float: none;
|
376 |
+
}
|
377 |
+
input.date-picker-field {
|
378 |
+
width: 50%;
|
379 |
+
min-width: inherit;
|
380 |
+
float: none;
|
381 |
+
display: inline;
|
382 |
+
}
|
383 |
+
input.minute, input.hour {
|
384 |
+
width: 2em;
|
385 |
+
min-width: inherit;
|
386 |
+
float: none;
|
387 |
+
display: inline;
|
388 |
+
}
|
389 |
+
}
|
390 |
+
td.attribute_name {
|
391 |
+
width: 200px;
|
392 |
+
}
|
393 |
+
.plus, .minus {
|
394 |
+
margin-top: 6px;
|
395 |
+
}
|
396 |
+
.fl {
|
397 |
+
float: left;
|
398 |
+
}
|
399 |
+
.fr {
|
400 |
+
float: right;
|
401 |
+
}
|
402 |
+
}
|
403 |
+
&:first-child {
|
404 |
+
/* main file */
|
405 |
+
h3 {
|
406 |
+
background: #EAF2FA;
|
407 |
+
background-image: linear-gradient(bottom, rgb(218,230,242) 0%, rgb(234,242,250) 100%);
|
408 |
+
background-image: -o-linear-gradient(bottom, rgb(218,230,242) 0%, rgb(234,242,250) 100%);
|
409 |
+
background-image: -moz-linear-gradient(bottom, rgb(218,230,242) 0%, rgb(234,242,250) 100%);
|
410 |
+
background-image: -webkit-linear-gradient(bottom, rgb(218,230,242) 0%, rgb(234,242,250) 100%);
|
411 |
+
background-image: -ms-linear-gradient(bottom, rgb(218,230,242) 0%, rgb(234,242,250) 100%);
|
412 |
+
|
413 |
+
background-image: -webkit-gradient(
|
414 |
+
linear,
|
415 |
+
left bottom,
|
416 |
+
left top,
|
417 |
+
color-stop(0, rgb(218,230,242)),
|
418 |
+
color-stop(1, rgb(234,242,250))
|
419 |
+
);
|
420 |
+
border-color: #d3deea;
|
421 |
+
color: #21759B;
|
422 |
+
}
|
423 |
+
}
|
424 |
+
}
|
425 |
+
.plus {
|
426 |
+
padding-left: 20px;
|
427 |
+
background: #fefefe url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAARklEQVQYGWP8//8/AzGACV3Rnj17/oMwujiGQnQFMD7RChlBbsRmFcwkEO3i4sJImonIumGmg0xBFifaRKIVgj2DbAUuNgCfThpracSKqwAAAABJRU5ErkJggg==) no-repeat 7px 5px;
|
428 |
+
}
|
429 |
+
.minus {
|
430 |
+
padding-left: 20px;
|
431 |
+
background: #fefefe url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAKUlEQVQYlWP8//8/Az7AhFeWGAUsDAwMDHv27MFqj4uLCyNBExhp70gAohwKC5KJ+HQAAAAASUVORK5CYII=) no-repeat 7px 6px;
|
432 |
+
}
|
433 |
+
.dlm_upload_file {
|
434 |
+
padding-left: 20px;
|
435 |
+
background: #fefefe url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAMklEQVQYV2NkQAK7d+/+D+K6uroywoThDJgkTAKmCKwAXRJZESMuSQwrkE3C6gbaKQAAYS4fOXZlROQAAAAASUVORK5CYII=) no-repeat 7px 5px;
|
436 |
+
}
|
437 |
+
.browse_for_file {
|
438 |
+
padding-left: 20px;
|
439 |
+
background: #fefefe url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAK0lEQVQYV2NkIAAYd+/e/R+mxtXVlRFdPYoCbIaBFWDTCVIMkqOXAnw+BQCbpycpLX4gIQAAAABJRU5ErkJggg==) no-repeat 7px 5px;
|
440 |
+
}
|
441 |
+
}
|
442 |
+
}
|
443 |
+
|
444 |
+
/* Writepanel forms */
|
445 |
+
#download-monitor-options {
|
446 |
+
.inside {
|
447 |
+
padding: 0;
|
448 |
+
margin: 0;
|
449 |
+
}
|
450 |
+
.form-field-checkbox {
|
451 |
+
label {
|
452 |
+
display: inline;
|
453 |
+
padding: 0 0 4px;
|
454 |
+
}
|
455 |
+
input {
|
456 |
+
display: inline;
|
457 |
+
width: auto;
|
458 |
+
vertical-align: middle;
|
459 |
+
}
|
460 |
+
.description {
|
461 |
+
padding: 4px 0 0 0;
|
462 |
+
display: block;
|
463 |
+
}
|
464 |
+
}
|
465 |
+
.access_permissions {
|
466 |
+
margin: 0 !important;
|
467 |
+
border-top: 1px solid white;
|
468 |
+
border-bottom: 1px solid #DFDFDF;
|
469 |
+
padding: 7px 12px !important;
|
470 |
+
overflow: hidden;
|
471 |
+
zoom: 1;
|
472 |
+
|
473 |
+
h4 {
|
474 |
+
margin-bottom: .5em;
|
475 |
+
margin: 0 0 .5em;
|
476 |
+
}
|
477 |
+
ul {
|
478 |
+
background: #fff;
|
479 |
+
border: 1px solid #dfdfdf;
|
480 |
+
height: 110px;
|
481 |
+
overflow: auto;
|
482 |
+
padding: .5em .9em;
|
483 |
+
margin: 0;
|
484 |
+
}
|
485 |
+
}
|
486 |
+
p {
|
487 |
+
margin: 0 !important;
|
488 |
+
border-top: 1px solid white;
|
489 |
+
border-bottom: 1px solid #DFDFDF;
|
490 |
+
padding: 7px 12px !important;
|
491 |
+
overflow: hidden;
|
492 |
+
zoom: 1;
|
493 |
+
}
|
494 |
+
}
|
495 |
+
|
496 |
+
#insert-download {
|
497 |
+
padding: 20px 20px;
|
498 |
+
|
499 |
+
.updated, .error {
|
500 |
+
margin-left: 0;
|
501 |
+
margin-right: 0;
|
502 |
+
}
|
503 |
+
h2 {
|
504 |
+
margin-top: 0;
|
505 |
+
}
|
506 |
+
label {
|
507 |
+
margin: 0 0 .25em 0;
|
508 |
+
display: block;
|
509 |
+
font-size: 1.1em;
|
510 |
+
}
|
511 |
+
span.description {
|
512 |
+
display: block;
|
513 |
+
}
|
514 |
+
select.input, input.input {
|
515 |
+
margin: 0 0 .25em 0;
|
516 |
+
display: block;
|
517 |
+
width: 100%;
|
518 |
+
font-size: 1.1em;
|
519 |
+
}
|
520 |
+
.add_link {
|
521 |
+
float: right;
|
522 |
+
}
|
523 |
+
}
|
assets/css/frontend.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.download-box{width:250px;border:1px solid #ccc;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;text-align:center;position:relative;margin:1em auto;box-shadow:0 2px 4px rgba(0,0,0,0.1),inset 0 1px 0 rgba(255,255,255,0.4)}.download-box img.wp-post-image{margin:0;padding:0;display:block;width:100%;-moz-border-radius:0;-webkit-border-radius:0;-moz-border-top-left-radius:3px;-moz-border-top-right-radius:3px;-webkit-border-top-left-radius:3px;-webkit-border-top-right-radius:3px;border-radius:0;border-top-left-radius:3px;border-top-right-radius:3px;box-shadow:inset 0 1px 0 rgba(255,255,255,0.4)}.download-box .download-box-content{padding:0 1em 1em}.download-box .download-count{-moz-border-radius:1em;-webkit-border-radius:1em;border-radius:1em;color:#777;text-shadow:0 1px 0 rgba(255,255,255,0.5);background:#ddd;box-shadow:0 2px 4px rgba(0,0,0,0.1),inset 0 1px 0 rgba(255,255,255,0.4);position:absolute;top:0;right:0;padding:.5em;height:1em;width:auto;min-width:1em;font-size:1em;text-align:center;vertical-align:middle;line-height:1em;border:1px solid #bbb;margin:-0.5em -0.5em 0 0}.download-button{text-align:center;text-decoration:none;padding:.75em 1em;color:#fff;display:block;font-size:1.2em;line-height:1.5em;background-color:#09c;background-image:-webkit-linear-gradient(#009fd4,#09c,#0086b2);background-image:-moz-linear-gradient(#009fd4,#09c,#0086b2);-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;text-shadow:0 -1px 0 rgba(0,0,0,0.5);box-shadow:0 2px 4px rgba(0,0,0,0.3),inset 0 1px 0 rgba(255,255,255,0.4);border:1px solid #0086b2;cursor:pointer}.download-button:hover{color:#fff;background-color:#09c;background-image:-webkit-linear-gradient(#09c,#0086b2);background-image:-moz-linear-gradient(#09c,#0086b2)}.download-button small{font-size:.8em;opacity:.8;display:block}.filetype-icon{padding-left:19px;background-repeat:no-repeat;background-position:left;background-image:url(../images/filetypes/document.png)}.filetype-pdf{background-image:url(../images/filetypes/document-pdf.png)}.filetype-m4r,.filetype-au,.filetype-snd,.filetype-mid,.filetype-midi,.filetype-kar,.filetype-mpga,.filetype-mp2,.filetype-mp3,.filetype-aif,.filetype-aiff,.filetype-aifc,.filetype-m3u,.filetype-ram,.filetype-rm,.filetype-rpm,.filetype-ra,.filetype-wav,.filetype-wave{background-image:url(../images/filetypes/document-music.png)}.filetype-mpeg,.filetype-mpg,.filetype-mpe,.filetype-qt,.filetype-mov,.filetype-mxu,.filetype-avi,.filetype-movie,.filetype-mp4,.filetype-divx{background-image:url(../images/filetypes/document-film.png)}.filetype-zip,.filetype-gz,.filetype-rar,.filetype-sit,.filetype-tar,.filetype-7z{background-image:url(../images/filetypes/document-zipper.png)}.filetype-xls,.filetype-tsv,.filetype-csv{background-image:url(../images/filetypes/document-excel.png)}.filetype-doc{background-image:url(../images/filetypes/document-word-text.png)}.filetype-ai{background-image:url(../images/filetypes/document-illustrator.png)}.filetype-swf{background-image:url(../images/filetypes/document-flash-movie.png)}.filetype-eps,.filetype-ps,.filetype-bmp,.filetype-gif,.filetype-ief,.filetype-jpeg,.filetype-jpg,.filetype-jpe,.filetype-png,.filetype-tiff,.filetype-tif,.filetype-djv,.filetype-wbmp,.filetype-ras,.filetype-pnm,.filetype-pbm,.filetype-pgm,.filetype-ppm,.filetype-rgb,.filetype-xbm,.filetype-xpm,.filetype-xwd{background-image:url(../images/filetypes/document-image.png)}.filetype-psd{background-image:url(../images/filetypes/document-photoshop.png)}.filetype-ppt{background-image:url(../images/filetypes/document-powerpoint.png)}.filetype-js,.filetype-css,.filetype-as,.filetype-htm,.filetype-htaccess,.filetype-sql,.filetype-html,.filetype-php,.filetype-xml,.filetype-xsl{background-image:url(../images/filetypes/document-code.png)}.filetype-rtx,.filetype-rtf{background-image:url(../images/filetypes/document-text-image.png)}.filetype-txt{background-image:url(../images/filetypes/document-text.png)}
|
assets/css/frontend.less
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.download-box {
|
2 |
+
width: 250px;
|
3 |
+
border: 1px solid #ccc;
|
4 |
+
-moz-border-radius: 4px;
|
5 |
+
-webkit-border-radius: 4px;
|
6 |
+
border-radius: 4px;
|
7 |
+
text-align: center;
|
8 |
+
position: relative;
|
9 |
+
margin: 1em auto;
|
10 |
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1),inset 0 1px 0 rgba(255,255,255,0.4);
|
11 |
+
|
12 |
+
img.wp-post-image {
|
13 |
+
margin: 0;
|
14 |
+
padding: 0;
|
15 |
+
display: block;
|
16 |
+
width: 100%;
|
17 |
+
-moz-border-radius: 0;
|
18 |
+
-webkit-border-radius: 0;
|
19 |
+
-moz-border-top-left-radius: 3px;
|
20 |
+
-moz-border-top-right-radius: 3px;
|
21 |
+
-webkit-border-top-left-radius: 3px;
|
22 |
+
-webkit-border-top-right-radius: 3px;
|
23 |
+
border-radius: 0;
|
24 |
+
border-top-left-radius: 3px;
|
25 |
+
border-top-right-radius: 3px;
|
26 |
+
box-shadow: inset 0 1px 0 rgba(255,255,255,0.4);
|
27 |
+
}
|
28 |
+
|
29 |
+
.download-box-content {
|
30 |
+
padding: 0 1em 1em;
|
31 |
+
}
|
32 |
+
|
33 |
+
.download-count {
|
34 |
+
-moz-border-radius: 1em;
|
35 |
+
-webkit-border-radius: 1em;
|
36 |
+
border-radius: 1em;
|
37 |
+
color: #777;
|
38 |
+
text-shadow: 0 1px 0 rgba(255,255,255,0.5);
|
39 |
+
background: #ddd;
|
40 |
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1), inset 0 1px 0 rgba(255,255,255,0.4);
|
41 |
+
position: absolute;
|
42 |
+
top: 0;
|
43 |
+
right: 0;
|
44 |
+
padding: .5em;
|
45 |
+
height: 1em;
|
46 |
+
width: auto;
|
47 |
+
min-width: 1em;
|
48 |
+
font-size: 1em;
|
49 |
+
text-align: center;
|
50 |
+
vertical-align: middle;
|
51 |
+
line-height: 1em;
|
52 |
+
border: 1px solid #bbb;
|
53 |
+
margin: -.5em -.5em 0 0;
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
.download-button {
|
58 |
+
text-align: center;
|
59 |
+
text-decoration: none;
|
60 |
+
padding: 0.75em 1em;
|
61 |
+
color: #fff;
|
62 |
+
display: block;
|
63 |
+
font-size: 1.2em;
|
64 |
+
line-height: 1.5em;
|
65 |
+
background-color: #0099cc;
|
66 |
+
background-image: -webkit-linear-gradient(#009fd4, #0099cc, #0086b2);
|
67 |
+
background-image: -moz-linear-gradient(#009fd4, #0099cc, #0086b2);
|
68 |
+
-moz-border-radius: 4px;
|
69 |
+
-webkit-border-radius: 4px;
|
70 |
+
border-radius: 4px;
|
71 |
+
text-shadow: 0 -1px 0 rgba(0,0,0,0.5);
|
72 |
+
box-shadow: 0 2px 4px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.4);
|
73 |
+
border: 1px solid #0086b2;
|
74 |
+
cursor: pointer;
|
75 |
+
|
76 |
+
&:hover {
|
77 |
+
color: #fff;
|
78 |
+
background-color: #0099cc;
|
79 |
+
background-image: -webkit-linear-gradient(#0099cc, #0086b2);
|
80 |
+
background-image: -moz-linear-gradient(#0099cc, #0086b2);
|
81 |
+
}
|
82 |
+
|
83 |
+
small {
|
84 |
+
font-size: 0.8em;
|
85 |
+
opacity: 0.8;
|
86 |
+
display: block;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
.filetype-icon {
|
91 |
+
padding-left: 19px;
|
92 |
+
background-repeat: no-repeat;
|
93 |
+
background-position: left;
|
94 |
+
background-image: url(../images/filetypes/document.png);
|
95 |
+
}
|
96 |
+
.filetype-pdf {
|
97 |
+
background-image: url(../images/filetypes/document-pdf.png);
|
98 |
+
}
|
99 |
+
.filetype-m4r, .filetype-au, .filetype-snd, .filetype-mid, .filetype-midi, .filetype-kar, .filetype-mpga, .filetype-mp2, .filetype-mp3, .filetype-aif, .filetype-aiff, .filetype-aifc, .filetype-m3u, .filetype-ram, .filetype-rm, .filetype-rpm, .filetype-ra, .filetype-wav, .filetype-wave {
|
100 |
+
background-image: url(../images/filetypes/document-music.png);
|
101 |
+
}
|
102 |
+
.filetype-mpeg, .filetype-mpg, .filetype-mpe, .filetype-qt, .filetype-mov, .filetype-mxu, .filetype-avi, .filetype-movie, .filetype-mp4, .filetype-divx {
|
103 |
+
background-image: url(../images/filetypes/document-film.png);
|
104 |
+
}
|
105 |
+
.filetype-zip, .filetype-gz, .filetype-rar, .filetype-sit, .filetype-tar, .filetype-7z {
|
106 |
+
background-image: url(../images/filetypes/document-zipper.png);
|
107 |
+
}
|
108 |
+
.filetype-xls, .filetype-tsv, .filetype-csv {
|
109 |
+
background-image: url(../images/filetypes/document-excel.png);
|
110 |
+
}
|
111 |
+
.filetype-doc {
|
112 |
+
background-image: url(../images/filetypes/document-word-text.png);
|
113 |
+
}
|
114 |
+
.filetype-ai {
|
115 |
+
background-image: url(../images/filetypes/document-illustrator.png);
|
116 |
+
}
|
117 |
+
.filetype-swf {
|
118 |
+
background-image: url(../images/filetypes/document-flash-movie.png);
|
119 |
+
}
|
120 |
+
.filetype-eps, .filetype-ps, .filetype-bmp, .filetype-gif, .filetype-ief, .filetype-jpeg, .filetype-jpg, .filetype-jpe, .filetype-png, .filetype-tiff, .filetype-tif, .filetype-djv, .filetype-wbmp, .filetype-ras, .filetype-pnm, .filetype-pbm, .filetype-pgm, .filetype-ppm, .filetype-rgb, .filetype-xbm, .filetype-xpm, .filetype-xwd {
|
121 |
+
background-image: url(../images/filetypes/document-image.png);
|
122 |
+
}
|
123 |
+
.filetype-psd {
|
124 |
+
background-image: url(../images/filetypes/document-photoshop.png);
|
125 |
+
}
|
126 |
+
.filetype-ppt {
|
127 |
+
background-image: url(../images/filetypes/document-powerpoint.png);
|
128 |
+
}
|
129 |
+
.filetype-js, .filetype-css, .filetype-as, .filetype-htm, .filetype-htaccess, .filetype-sql, .filetype-html, .filetype-php, .filetype-xml, .filetype-xsl {
|
130 |
+
background-image: url(../images/filetypes/document-code.png);
|
131 |
+
}
|
132 |
+
.filetype-rtx, .filetype-rtf {
|
133 |
+
background-image: url(../images/filetypes/document-text-image.png);
|
134 |
+
}
|
135 |
+
.filetype-txt {
|
136 |
+
background-image: url(../images/filetypes/document-text.png);
|
137 |
+
}
|
assets/images/ajax-loader.gif
ADDED
Binary file
|
assets/images/cross.png
ADDED
Binary file
|
assets/images/download_count_head.png
ADDED
Binary file
|
assets/images/downloads-icon.gif
ADDED
Binary file
|
assets/images/featured_head.png
ADDED
Binary file
|
assets/images/filetypes/document-code.png
ADDED
Binary file
|
assets/images/filetypes/document-excel.png
ADDED
Binary file
|
assets/images/filetypes/document-film.png
ADDED
Binary file
|
assets/images/filetypes/document-flash-movie.png
ADDED
Binary file
|
assets/images/filetypes/document-illustrator.png
ADDED
Binary file
|
assets/images/filetypes/document-image.png
ADDED
Binary file
|
assets/images/filetypes/document-music.png
ADDED
Binary file
|
assets/images/filetypes/document-pdf.png
ADDED
Binary file
|
assets/images/filetypes/document-photoshop.png
ADDED
Binary file
|
assets/images/filetypes/document-powerpoint.png
ADDED
Binary file
|
assets/images/filetypes/document-text-image.png
ADDED
Binary file
|
assets/images/filetypes/document-text.png
ADDED
Binary file
|
assets/images/filetypes/document-word-text.png
ADDED
Binary file
|
assets/images/filetypes/document-zipper.png
ADDED
Binary file
|
assets/images/filetypes/document.png
ADDED
Binary file
|
assets/images/filetypes/readme.txt
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Fugue Icons
|
2 |
+
|
3 |
+
Copyright (C) 2010 Yusuke Kamiyamane. All rights reserved.
|
4 |
+
The icons are licensed under a Creative Commons Attribution
|
5 |
+
3.0 license. <http://creativecommons.org/licenses/by/3.0/>
|
6 |
+
|
7 |
+
If you can't or don't want to provide a link back, please
|
8 |
+
purchase a royalty-free license. <http://pinvoke.com/>
|
9 |
+
|
10 |
+
I'm unavailable for custom icon design work. But your
|
11 |
+
suggestions are always welcome!
|
12 |
+
<mailto:yusuke.kamiyamane@gmail.com>
|
13 |
+
|
14 |
+
------------------------------------------------------------
|
15 |
+
|
16 |
+
- geotag
|
17 |
+
|
18 |
+
Copyright (C) Geotag Icon Project. All rights reserved.
|
19 |
+
<http://www.geotagicons.com/>
|
20 |
+
|
21 |
+
Geotag icon is licensed under a Creative Commons
|
22 |
+
Attribution-Share Alike 3.0 license or LGPL.
|
23 |
+
<http://creativecommons.org/licenses/by-sa/3.0/>
|
24 |
+
<http://opensource.org/licenses/lgpl-license.php>
|
25 |
+
|
26 |
+
- language
|
27 |
+
|
28 |
+
Copyright (C) Language Icon Project. All rights reserved.
|
29 |
+
<http://www.languageicon.org/>
|
30 |
+
|
31 |
+
Language icon is licensed under a Creative Commons
|
32 |
+
Attribution-Share Alike 3.0 license.
|
33 |
+
<http://creativecommons.org/licenses/by-sa/3.0/>
|
34 |
+
|
35 |
+
- open-share
|
36 |
+
|
37 |
+
Copyright (C) Open Share Icon Project. All rights reserved.
|
38 |
+
<http://www.openshareicons.com/>
|
39 |
+
|
40 |
+
Open Share icon is licensed under a Creative Commons
|
41 |
+
Attribution-Share Alike 3.0 license.
|
42 |
+
<http://creativecommons.org/licenses/by-sa/3.0/>
|
43 |
+
|
44 |
+
- opml
|
45 |
+
|
46 |
+
Copyright (C) OPML Icon Project. All rights reserved.
|
47 |
+
<http://opmlicons.com/>
|
48 |
+
|
49 |
+
OPML icon is licensed under a Creative Commons
|
50 |
+
Attribution-Share Alike 2.5 license.
|
51 |
+
<http://creativecommons.org/licenses/by-sa/2.5/>
|
52 |
+
|
53 |
+
- share
|
54 |
+
|
55 |
+
Copyright (C) Share Icon Project. All rights reserved.
|
56 |
+
<http://shareicons.com/>
|
57 |
+
|
58 |
+
Share icon is licensed under a GPL or LGPL or BSD or
|
59 |
+
Creative Commons Attribution 2.5 license.
|
60 |
+
<http://opensource.org/licenses/gpl-license.php>
|
61 |
+
<http://opensource.org/licenses/lgpl-license.php>
|
62 |
+
<http://opensource.org/licenses/bsd-license.php>
|
63 |
+
<http://creativecommons.org/licenses/by/2.5/>
|
assets/images/folder-horizontal-open.png
ADDED
Binary file
|
assets/images/folder-horizontal.png
ADDED
Binary file
|
assets/images/media-button-download.gif
ADDED
Binary file
|
assets/images/member_head.png
ADDED
Binary file
|
assets/images/menu_icon.png
ADDED
Binary file
|
assets/images/on.png
ADDED
Binary file
|
assets/images/placeholder.png
ADDED
Binary file
|
assets/js/blockui.js
ADDED
@@ -0,0 +1,499 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* jQuery blockUI plugin
|
3 |
+
* Version 2.39 (23-MAY-2011)
|
4 |
+
* @requires jQuery v1.2.3 or later
|
5 |
+
*
|
6 |
+
* Examples at: http://malsup.com/jquery/block/
|
7 |
+
* Copyright (c) 2007-2010 M. Alsup
|
8 |
+
* Dual licensed under the MIT and GPL licenses:
|
9 |
+
* http://www.opensource.org/licenses/mit-license.php
|
10 |
+
* http://www.gnu.org/licenses/gpl.html
|
11 |
+
*
|
12 |
+
* Thanks to Amir-Hossein Sobhi for some excellent contributions!
|
13 |
+
*/
|
14 |
+
|
15 |
+
;(function($) {
|
16 |
+
|
17 |
+
if (/1\.(0|1|2)\.(0|1|2)/.test($.fn.jquery) || /^1.1/.test($.fn.jquery)) {
|
18 |
+
alert('blockUI requires jQuery v1.2.3 or later! You are using v' + $.fn.jquery);
|
19 |
+
return;
|
20 |
+
}
|
21 |
+
|
22 |
+
$.fn._fadeIn = $.fn.fadeIn;
|
23 |
+
|
24 |
+
var noOp = function() {};
|
25 |
+
|
26 |
+
// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
|
27 |
+
// retarded userAgent strings on Vista)
|
28 |
+
var mode = document.documentMode || 0;
|
29 |
+
var setExpr = $.browser.msie && (($.browser.version < 8 && !mode) || mode < 8);
|
30 |
+
var ie6 = $.browser.msie && /MSIE 6.0/.test(navigator.userAgent) && !mode;
|
31 |
+
|
32 |
+
// global $ methods for blocking/unblocking the entire page
|
33 |
+
$.blockUI = function(opts) { install(window, opts); };
|
34 |
+
$.unblockUI = function(opts) { remove(window, opts); };
|
35 |
+
|
36 |
+
// convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
|
37 |
+
$.growlUI = function(title, message, timeout, onClose) {
|
38 |
+
var $m = $('<div class="growlUI"></div>');
|
39 |
+
if (title) $m.append('<h1>'+title+'</h1>');
|
40 |
+
if (message) $m.append('<h2>'+message+'</h2>');
|
41 |
+
if (timeout == undefined) timeout = 3000;
|
42 |
+
$.blockUI({
|
43 |
+
message: $m, fadeIn: 700, fadeOut: 1000, centerY: false,
|
44 |
+
timeout: timeout, showOverlay: false,
|
45 |
+
onUnblock: onClose,
|
46 |
+
css: $.blockUI.defaults.growlCSS
|
47 |
+
});
|
48 |
+
};
|
49 |
+
|
50 |
+
// plugin method for blocking element content
|
51 |
+
$.fn.block = function(opts) {
|
52 |
+
return this.unblock({ fadeOut: 0 }).each(function() {
|
53 |
+
if ($.css(this,'position') == 'static')
|
54 |
+
this.style.position = 'relative';
|
55 |
+
if ($.browser.msie)
|
56 |
+
this.style.zoom = 1; // force 'hasLayout'
|
57 |
+
install(this, opts);
|
58 |
+
});
|
59 |
+
};
|
60 |
+
|
61 |
+
// plugin method for unblocking element content
|
62 |
+
$.fn.unblock = function(opts) {
|
63 |
+
return this.each(function() {
|
64 |
+
remove(this, opts);
|
65 |
+
});
|
66 |
+
};
|
67 |
+
|
68 |
+
$.blockUI.version = 2.39; // 2nd generation blocking at no extra cost!
|
69 |
+
|
70 |
+
// override these in your code to change the default behavior and style
|
71 |
+
$.blockUI.defaults = {
|
72 |
+
// message displayed when blocking (use null for no message)
|
73 |
+
message: '<h1>Please wait...</h1>',
|
74 |
+
|
75 |
+
title: null, // title string; only used when theme == true
|
76 |
+
draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
|
77 |
+
|
78 |
+
theme: false, // set to true to use with jQuery UI themes
|
79 |
+
|
80 |
+
// styles for the message when blocking; if you wish to disable
|
81 |
+
// these and use an external stylesheet then do this in your code:
|
82 |
+
// $.blockUI.defaults.css = {};
|
83 |
+
css: {
|
84 |
+
padding: 0,
|
85 |
+
margin: 0,
|
86 |
+
width: '30%',
|
87 |
+
top: '40%',
|
88 |
+
left: '35%',
|
89 |
+
textAlign: 'center',
|
90 |
+
color: '#000',
|
91 |
+
border: '3px solid #aaa',
|
92 |
+
backgroundColor:'#fff',
|
93 |
+
cursor: 'wait'
|
94 |
+
},
|
95 |
+
|
96 |
+
// minimal style set used when themes are used
|
97 |
+
themedCSS: {
|
98 |
+
width: '30%',
|
99 |
+
top: '40%',
|
100 |
+
left: '35%'
|
101 |
+
},
|
102 |
+
|
103 |
+
// styles for the overlay
|
104 |
+
overlayCSS: {
|
105 |
+
backgroundColor: '#000',
|
106 |
+
opacity: 0.6,
|
107 |
+
cursor: 'wait'
|
108 |
+
},
|
109 |
+
|
110 |
+
// styles applied when using $.growlUI
|
111 |
+
growlCSS: {
|
112 |
+
width: '350px',
|
113 |
+
top: '10px',
|
114 |
+
left: '',
|
115 |
+
right: '10px',
|
116 |
+
border: 'none',
|
117 |
+
padding: '5px',
|
118 |
+
opacity: 0.6,
|
119 |
+
cursor: 'default',
|
120 |
+
color: '#fff',
|
121 |
+
backgroundColor: '#000',
|
122 |
+
'-webkit-border-radius': '10px',
|
123 |
+
'-moz-border-radius': '10px',
|
124 |
+
'border-radius': '10px'
|
125 |
+
},
|
126 |
+
|
127 |
+
// IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
|
128 |
+
// (hat tip to Jorge H. N. de Vasconcelos)
|
129 |
+
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
|
130 |
+
|
131 |
+
// force usage of iframe in non-IE browsers (handy for blocking applets)
|
132 |
+
forceIframe: false,
|
133 |
+
|
134 |
+
// z-index for the blocking overlay
|
135 |
+
baseZ: 1000,
|
136 |
+
|
137 |
+
// set these to true to have the message automatically centered
|
138 |
+
centerX: true, // <-- only effects element blocking (page block controlled via css above)
|
139 |
+
centerY: true,
|
140 |
+
|
141 |
+
// allow body element to be stetched in ie6; this makes blocking look better
|
142 |
+
// on "short" pages. disable if you wish to prevent changes to the body height
|
143 |
+
allowBodyStretch: true,
|
144 |
+
|
145 |
+
// enable if you want key and mouse events to be disabled for content that is blocked
|
146 |
+
bindEvents: true,
|
147 |
+
|
148 |
+
// be default blockUI will supress tab navigation from leaving blocking content
|
149 |
+
// (if bindEvents is true)
|
150 |
+
constrainTabKey: true,
|
151 |
+
|
152 |
+
// fadeIn time in millis; set to 0 to disable fadeIn on block
|
153 |
+
fadeIn: 200,
|
154 |
+
|
155 |
+
// fadeOut time in millis; set to 0 to disable fadeOut on unblock
|
156 |
+
fadeOut: 400,
|
157 |
+
|
158 |
+
// time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
|
159 |
+
timeout: 0,
|
160 |
+
|
161 |
+
// disable if you don't want to show the overlay
|
162 |
+
showOverlay: true,
|
163 |
+
|
164 |
+
// if true, focus will be placed in the first available input field when
|
165 |
+
// page blocking
|
166 |
+
focusInput: true,
|
167 |
+
|
168 |
+
// suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
|
169 |
+
applyPlatformOpacityRules: true,
|
170 |
+
|
171 |
+
// callback method invoked when fadeIn has completed and blocking message is visible
|
172 |
+
onBlock: null,
|
173 |
+
|
174 |
+
// callback method invoked when unblocking has completed; the callback is
|
175 |
+
// passed the element that has been unblocked (which is the window object for page
|
176 |
+
// blocks) and the options that were passed to the unblock call:
|
177 |
+
// onUnblock(element, options)
|
178 |
+
onUnblock: null,
|
179 |
+
|
180 |
+
// don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
|
181 |
+
quirksmodeOffsetHack: 4,
|
182 |
+
|
183 |
+
// class name of the message block
|
184 |
+
blockMsgClass: 'blockMsg'
|
185 |
+
};
|
186 |
+
|
187 |
+
// private data and functions follow...
|
188 |
+
|
189 |
+
var pageBlock = null;
|
190 |
+
var pageBlockEls = [];
|
191 |
+
|
192 |
+
function install(el, opts) {
|
193 |
+
var full = (el == window);
|
194 |
+
var msg = opts && opts.message !== undefined ? opts.message : undefined;
|
195 |
+
opts = $.extend({}, $.blockUI.defaults, opts || {});
|
196 |
+
opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
|
197 |
+
var css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
|
198 |
+
var themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
|
199 |
+
msg = msg === undefined ? opts.message : msg;
|
200 |
+
|
201 |
+
// remove the current block (if there is one)
|
202 |
+
if (full && pageBlock)
|
203 |
+
remove(window, {fadeOut:0});
|
204 |
+
|
205 |
+
// if an existing element is being used as the blocking content then we capture
|
206 |
+
// its current place in the DOM (and current display style) so we can restore
|
207 |
+
// it when we unblock
|
208 |
+
if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
|
209 |
+
var node = msg.jquery ? msg[0] : msg;
|
210 |
+
var data = {};
|
211 |
+
$(el).data('blockUI.history', data);
|
212 |
+
data.el = node;
|
213 |
+
data.parent = node.parentNode;
|
214 |
+
data.display = node.style.display;
|
215 |
+
data.position = node.style.position;
|
216 |
+
if (data.parent)
|
217 |
+
data.parent.removeChild(node);
|
218 |
+
}
|
219 |
+
|
220 |
+
$(el).data('blockUI.onUnblock', opts.onUnblock);
|
221 |
+
var z = opts.baseZ;
|
222 |
+
|
223 |
+
// blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
|
224 |
+
// layer1 is the iframe layer which is used to supress bleed through of underlying content
|
225 |
+
// layer2 is the overlay layer which has opacity and a wait cursor (by default)
|
226 |
+
// layer3 is the message content that is displayed while blocking
|
227 |
+
|
228 |
+
var lyr1 = ($.browser.msie || opts.forceIframe)
|
229 |
+
? $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>')
|
230 |
+
: $('<div class="blockUI" style="display:none"></div>');
|
231 |
+
|
232 |
+
var lyr2 = opts.theme
|
233 |
+
? $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>')
|
234 |
+
: $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
|
235 |
+
|
236 |
+
var lyr3, s;
|
237 |
+
if (opts.theme && full) {
|
238 |
+
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">' +
|
239 |
+
'<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>' +
|
240 |
+
'<div class="ui-widget-content ui-dialog-content"></div>' +
|
241 |
+
'</div>';
|
242 |
+
}
|
243 |
+
else if (opts.theme) {
|
244 |
+
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">' +
|
245 |
+
'<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || ' ')+'</div>' +
|
246 |
+
'<div class="ui-widget-content ui-dialog-content"></div>' +
|
247 |
+
'</div>';
|
248 |
+
}
|
249 |
+
else if (full) {
|
250 |
+
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
|
251 |
+
}
|
252 |
+
else {
|
253 |
+
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
|
254 |
+
}
|
255 |
+
lyr3 = $(s);
|
256 |
+
|
257 |
+
// if we have a message, style it
|
258 |
+
if (msg) {
|
259 |
+
if (opts.theme) {
|
260 |
+
lyr3.css(themedCSS);
|
261 |
+
lyr3.addClass('ui-widget-content');
|
262 |
+
}
|
263 |
+
else
|
264 |
+
lyr3.css(css);
|
265 |
+
}
|
266 |
+
|
267 |
+
// style the overlay
|
268 |
+
if (!opts.theme && (!opts.applyPlatformOpacityRules || !($.browser.mozilla && /Linux/.test(navigator.platform))))
|
269 |
+
lyr2.css(opts.overlayCSS);
|
270 |
+
lyr2.css('position', full ? 'fixed' : 'absolute');
|
271 |
+
|
272 |
+
// make iframe layer transparent in IE
|
273 |
+
if ($.browser.msie || opts.forceIframe)
|
274 |
+
lyr1.css('opacity',0.0);
|
275 |
+
|
276 |
+
//$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
|
277 |
+
var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
|
278 |
+
$.each(layers, function() {
|
279 |
+
this.appendTo($par);
|
280 |
+
});
|
281 |
+
|
282 |
+
if (opts.theme && opts.draggable && $.fn.draggable) {
|
283 |
+
lyr3.draggable({
|
284 |
+
handle: '.ui-dialog-titlebar',
|
285 |
+
cancel: 'li'
|
286 |
+
});
|
287 |
+
}
|
288 |
+
|
289 |
+
// ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
|
290 |
+
var expr = setExpr && (!$.boxModel || $('object,embed', full ? null : el).length > 0);
|
291 |
+
if (ie6 || expr) {
|
292 |
+
// give body 100% height
|
293 |
+
if (full && opts.allowBodyStretch && $.boxModel)
|
294 |
+
$('html,body').css('height','100%');
|
295 |
+
|
296 |
+
// fix ie6 issue when blocked element has a border width
|
297 |
+
if ((ie6 || !$.boxModel) && !full) {
|
298 |
+
var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
|
299 |
+
var fixT = t ? '(0 - '+t+')' : 0;
|
300 |
+
var fixL = l ? '(0 - '+l+')' : 0;
|
301 |
+
}
|
302 |
+
|
303 |
+
// simulate fixed position
|
304 |
+
$.each([lyr1,lyr2,lyr3], function(i,o) {
|
305 |
+
var s = o[0].style;
|
306 |
+
s.position = 'absolute';
|
307 |
+
if (i < 2) {
|
308 |
+
full ? s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"')
|
309 |
+
: s.setExpression('height','this.parentNode.offsetHeight + "px"');
|
310 |
+
full ? s.setExpression('width','jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"')
|
311 |
+
: s.setExpression('width','this.parentNode.offsetWidth + "px"');
|
312 |
+
if (fixL) s.setExpression('left', fixL);
|
313 |
+
if (fixT) s.setExpression('top', fixT);
|
314 |
+
}
|
315 |
+
else if (opts.centerY) {
|
316 |
+
if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
|
317 |
+
s.marginTop = 0;
|
318 |
+
}
|
319 |
+
else if (!opts.centerY && full) {
|
320 |
+
var top = (opts.css && opts.css.top) ? parseInt(opts.css.top) : 0;
|
321 |
+
var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
|
322 |
+
s.setExpression('top',expression);
|
323 |
+
}
|
324 |
+
});
|
325 |
+
}
|
326 |
+
|
327 |
+
// show the message
|
328 |
+
if (msg) {
|
329 |
+
if (opts.theme)
|
330 |
+
lyr3.find('.ui-widget-content').append(msg);
|
331 |
+
else
|
332 |
+
lyr3.append(msg);
|
333 |
+
if (msg.jquery || msg.nodeType)
|
334 |
+
$(msg).show();
|
335 |
+
}
|
336 |
+
|
337 |
+
if (($.browser.msie || opts.forceIframe) && opts.showOverlay)
|
338 |
+
lyr1.show(); // opacity is zero
|
339 |
+
if (opts.fadeIn) {
|
340 |
+
var cb = opts.onBlock ? opts.onBlock : noOp;
|
341 |
+
var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
|
342 |
+
var cb2 = msg ? cb : noOp;
|
343 |
+
if (opts.showOverlay)
|
344 |
+
lyr2._fadeIn(opts.fadeIn, cb1);
|
345 |
+
if (msg)
|
346 |
+
lyr3._fadeIn(opts.fadeIn, cb2);
|
347 |
+
}
|
348 |
+
else {
|
349 |
+
if (opts.showOverlay)
|
350 |
+
lyr2.show();
|
351 |
+
if (msg)
|
352 |
+
lyr3.show();
|
353 |
+
if (opts.onBlock)
|
354 |
+
opts.onBlock();
|
355 |
+
}
|
356 |
+
|
357 |
+
// bind key and mouse events
|
358 |
+
bind(1, el, opts);
|
359 |
+
|
360 |
+
if (full) {
|
361 |
+
pageBlock = lyr3[0];
|
362 |
+
pageBlockEls = $(':input:enabled:visible',pageBlock);
|
363 |
+
if (opts.focusInput)
|
364 |
+
setTimeout(focus, 20);
|
365 |
+
}
|
366 |
+
else
|
367 |
+
center(lyr3[0], opts.centerX, opts.centerY);
|
368 |
+
|
369 |
+
if (opts.timeout) {
|
370 |
+
// auto-unblock
|
371 |
+
var to = setTimeout(function() {
|
372 |
+
full ? $.unblockUI(opts) : $(el).unblock(opts);
|
373 |
+
}, opts.timeout);
|
374 |
+
$(el).data('blockUI.timeout', to);
|
375 |
+
}
|
376 |
+
};
|
377 |
+
|
378 |
+
// remove the block
|
379 |
+
function remove(el, opts) {
|
380 |
+
var full = (el == window);
|
381 |
+
var $el = $(el);
|
382 |
+
var data = $el.data('blockUI.history');
|
383 |
+
var to = $el.data('blockUI.timeout');
|
384 |
+
if (to) {
|
385 |
+
clearTimeout(to);
|
386 |
+
$el.removeData('blockUI.timeout');
|
387 |
+
}
|
388 |
+
opts = $.extend({}, $.blockUI.defaults, opts || {});
|
389 |
+
bind(0, el, opts); // unbind events
|
390 |
+
|
391 |
+
if (opts.onUnblock === null) {
|
392 |
+
opts.onUnblock = $el.data('blockUI.onUnblock');
|
393 |
+
$el.removeData('blockUI.onUnblock');
|
394 |
+
}
|
395 |
+
|
396 |
+
var els;
|
397 |
+
if (full) // crazy selector to handle odd field errors in ie6/7
|
398 |
+
els = $('body').children().filter('.blockUI').add('body > .blockUI');
|
399 |
+
else
|
400 |
+
els = $('.blockUI', el);
|
401 |
+
|
402 |
+
if (full)
|
403 |
+
pageBlock = pageBlockEls = null;
|
404 |
+
|
405 |
+
if (opts.fadeOut) {
|
406 |
+
els.fadeOut(opts.fadeOut);
|
407 |
+
setTimeout(function() { reset(els,data,opts,el); }, opts.fadeOut);
|
408 |
+
}
|
409 |
+
else
|
410 |
+
reset(els, data, opts, el);
|
411 |
+
};
|
412 |
+
|
413 |
+
// move blocking element back into the DOM where it started
|
414 |
+
function reset(els,data,opts,el) {
|
415 |
+
els.each(function(i,o) {
|
416 |
+
// remove via DOM calls so we don't lose event handlers
|
417 |
+
if (this.parentNode)
|
418 |
+
this.parentNode.removeChild(this);
|
419 |
+
});
|
420 |
+
|
421 |
+
if (data && data.el) {
|
422 |
+
data.el.style.display = data.display;
|
423 |
+
data.el.style.position = data.position;
|
424 |
+
if (data.parent)
|
425 |
+
data.parent.appendChild(data.el);
|
426 |
+
$(el).removeData('blockUI.history');
|
427 |
+
}
|
428 |
+
|
429 |
+
if (typeof opts.onUnblock == 'function')
|
430 |
+
opts.onUnblock(el,opts);
|
431 |
+
};
|
432 |
+
|
433 |
+
// bind/unbind the handler
|
434 |
+
function bind(b, el, opts) {
|
435 |
+
var full = el == window, $el = $(el);
|
436 |
+
|
437 |
+
// don't bother unbinding if there is nothing to unbind
|
438 |
+
if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
|
439 |
+
return;
|
440 |
+
if (!full)
|
441 |
+
$el.data('blockUI.isBlocked', b);
|
442 |
+
|
443 |
+
// don't bind events when overlay is not in use or if bindEvents is false
|
444 |
+
if (!opts.bindEvents || (b && !opts.showOverlay))
|
445 |
+
return;
|
446 |
+
|
447 |
+
// bind anchors and inputs for mouse and key events
|
448 |
+
var events = 'mousedown mouseup keydown keypress';
|
449 |
+
b ? $(document).bind(events, opts, handler) : $(document).unbind(events, handler);
|
450 |
+
|
451 |
+
// former impl...
|
452 |
+
// var $e = $('a,:input');
|
453 |
+
// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
|
454 |
+
};
|
455 |
+
|
456 |
+
// event handler to suppress keyboard/mouse events when blocking
|
457 |
+
function handler(e) {
|
458 |
+
// allow tab navigation (conditionally)
|
459 |
+
if (e.keyCode && e.keyCode == 9) {
|
460 |
+
if (pageBlock && e.data.constrainTabKey) {
|
461 |
+
var els = pageBlockEls;
|
462 |
+
var fwd = !e.shiftKey && e.target === els[els.length-1];
|
463 |
+
var back = e.shiftKey && e.target === els[0];
|
464 |
+
if (fwd || back) {
|
465 |
+
setTimeout(function(){focus(back)},10);
|
466 |
+
return false;
|
467 |
+
}
|
468 |
+
}
|
469 |
+
}
|
470 |
+
var opts = e.data;
|
471 |
+
// allow events within the message content
|
472 |
+
if ($(e.target).parents('div.' + opts.blockMsgClass).length > 0)
|
473 |
+
return true;
|
474 |
+
|
475 |
+
// allow events for content that is not being blocked
|
476 |
+
return $(e.target).parents().children().filter('div.blockUI').length == 0;
|
477 |
+
};
|
478 |
+
|
479 |
+
function focus(back) {
|
480 |
+
if (!pageBlockEls)
|
481 |
+
return;
|
482 |
+
var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
|
483 |
+
if (e)
|
484 |
+
e.focus();
|
485 |
+
};
|
486 |
+
|
487 |
+
function center(el, x, y) {
|
488 |
+
var p = el.parentNode, s = el.style;
|
489 |
+
var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
|
490 |
+
var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
|
491 |
+
if (x) s.left = l > 0 ? (l+'px') : '0';
|
492 |
+
if (y) s.top = t > 0 ? (t+'px') : '0';
|
493 |
+
};
|
494 |
+
|
495 |
+
function sz(el, p) {
|
496 |
+
return parseInt($.css(el,p))||0;
|
497 |
+
};
|
498 |
+
|
499 |
+
})(jQuery);
|
assets/js/blockui.min.js
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* jQuery blockUI plugin
|
3 |
+
* Version 2.39 (23-MAY-2011)
|
4 |
+
* @requires jQuery v1.2.3 or later
|
5 |
+
*
|
6 |
+
* Examples at: http://malsup.com/jquery/block/
|
7 |
+
* Copyright (c) 2007-2010 M. Alsup
|
8 |
+
* Dual licensed under the MIT and GPL licenses:
|
9 |
+
* http://www.opensource.org/licenses/mit-license.php
|
10 |
+
* http://www.gnu.org/licenses/gpl.html
|
11 |
+
*
|
12 |
+
* Thanks to Amir-Hossein Sobhi for some excellent contributions!
|
13 |
+
*/(function(a){function h(c,h){var j=c==window,l=h&&h.message!==undefined?h.message:undefined;h=a.extend({},a.blockUI.defaults,h||{});h.overlayCSS=a.extend({},a.blockUI.defaults.overlayCSS,h.overlayCSS||{});var p=a.extend({},a.blockUI.defaults.css,h.css||{}),q=a.extend({},a.blockUI.defaults.themedCSS,h.themedCSS||{});l=l===undefined?h.message:l;j&&f&&i(window,{fadeOut:0});if(l&&typeof l!="string"&&(l.parentNode||l.jquery)){var r=l.jquery?l[0]:l,s={};a(c).data("blockUI.history",s);s.el=r;s.parent=r.parentNode;s.display=r.style.display;s.position=r.style.position;s.parent&&s.parent.removeChild(r)}a(c).data("blockUI.onUnblock",h.onUnblock);var t=h.baseZ,u=a.browser.msie||h.forceIframe?a('<iframe class="blockUI" style="z-index:'+t++ +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+h.iframeSrc+'"></iframe>'):a('<div class="blockUI" style="display:none"></div>'),v=h.theme?a('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+t++ +';display:none"></div>'):a('<div class="blockUI blockOverlay" style="z-index:'+t++ +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>'),w,x;h.theme&&j?x='<div class="blockUI '+h.blockMsgClass+' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(t+10)+';display:none;position:fixed">'+'<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(h.title||" ")+"</div>"+'<div class="ui-widget-content ui-dialog-content"></div>'+"</div>":h.theme?x='<div class="blockUI '+h.blockMsgClass+' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(t+10)+';display:none;position:absolute">'+'<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(h.title||" ")+"</div>"+'<div class="ui-widget-content ui-dialog-content"></div>'+"</div>":j?x='<div class="blockUI '+h.blockMsgClass+' blockPage" style="z-index:'+(t+10)+';display:none;position:fixed"></div>':x='<div class="blockUI '+h.blockMsgClass+' blockElement" style="z-index:'+(t+10)+';display:none;position:absolute"></div>';w=a(x);if(l)if(h.theme){w.css(q);w.addClass("ui-widget-content")}else w.css(p);!h.theme&&(!h.applyPlatformOpacityRules||!a.browser.mozilla||!/Linux/.test(navigator.platform))&&v.css(h.overlayCSS);v.css("position",j?"fixed":"absolute");(a.browser.msie||h.forceIframe)&&u.css("opacity",0);var y=[u,v,w],z=j?a("body"):a(c);a.each(y,function(){this.appendTo(z)});h.theme&&h.draggable&&a.fn.draggable&&w.draggable({handle:".ui-dialog-titlebar",cancel:"li"});var A=d&&(!a.boxModel||a("object,embed",j?null:c).length>0);if(e||A){j&&h.allowBodyStretch&&a.boxModel&&a("html,body").css("height","100%");if((e||!a.boxModel)&&!j)var B=o(c,"borderTopWidth"),C=o(c,"borderLeftWidth"),D=B?"(0 - "+B+")":0,E=C?"(0 - "+C+")":0;a.each([u,v,w],function(a,b){var c=b[0].style;c.position="absolute";if(a<2){j?c.setExpression("height","Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:"+h.quirksmodeOffsetHack+') + "px"'):c.setExpression("height",'this.parentNode.offsetHeight + "px"');j?c.setExpression("width",'jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'):c.setExpression("width",'this.parentNode.offsetWidth + "px"');E&&c.setExpression("left",E);D&&c.setExpression("top",D)}else if(h.centerY){j&&c.setExpression("top",'(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');c.marginTop=0}else if(!h.centerY&&j){var d=h.css&&h.css.top?parseInt(h.css.top):0,e="((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "+d+') + "px"';c.setExpression("top",e)}})}if(l){h.theme?w.find(".ui-widget-content").append(l):w.append(l);(l.jquery||l.nodeType)&&a(l).show()}(a.browser.msie||h.forceIframe)&&h.showOverlay&&u.show();if(h.fadeIn){var F=h.onBlock?h.onBlock:b,G=h.showOverlay&&!l?F:b,H=l?F:b;h.showOverlay&&v._fadeIn(h.fadeIn,G);l&&w._fadeIn(h.fadeIn,H)}else{h.showOverlay&&v.show();l&&w.show();h.onBlock&&h.onBlock()}k(1,c,h);if(j){f=w[0];g=a(":input:enabled:visible",f);h.focusInput&&setTimeout(m,20)}else n(w[0],h.centerX,h.centerY);if(h.timeout){var I=setTimeout(function(){j?a.unblockUI(h):a(c).unblock(h)},h.timeout);a(c).data("blockUI.timeout",I)}}function i(b,c){var d=b==window,e=a(b),h=e.data("blockUI.history"),i=e.data("blockUI.timeout");if(i){clearTimeout(i);e.removeData("blockUI.timeout")}c=a.extend({},a.blockUI.defaults,c||{});k(0,b,c);if(c.onUnblock===null){c.onUnblock=e.data("blockUI.onUnblock");e.removeData("blockUI.onUnblock")}var l;d?l=a("body").children().filter(".blockUI").add("body > .blockUI"):l=a(".blockUI",b);d&&(f=g=null);if(c.fadeOut){l.fadeOut(c.fadeOut);setTimeout(function(){j(l,h,c,b)},c.fadeOut)}else j(l,h,c,b)}function j(b,c,d,e){b.each(function(a,b){this.parentNode&&this.parentNode.removeChild(this)});if(c&&c.el){c.el.style.display=c.display;c.el.style.position=c.position;c.parent&&c.parent.appendChild(c.el);a(e).removeData("blockUI.history")}typeof d.onUnblock=="function"&&d.onUnblock(e,d)}function k(b,c,d){var e=c==window,g=a(c);if(!b&&(e&&!f||!e&&!g.data("blockUI.isBlocked")))return;e||g.data("blockUI.isBlocked",b);if(!d.bindEvents||b&&!d.showOverlay)return;var h="mousedown mouseup keydown keypress";b?a(document).bind(h,d,l):a(document).unbind(h,l)}function l(b){if(b.keyCode&&b.keyCode==9&&f&&b.data.constrainTabKey){var c=g,d=!b.shiftKey&&b.target===c[c.length-1],e=b.shiftKey&&b.target===c[0];if(d||e){setTimeout(function(){m(e)},10);return!1}}var h=b.data;return a(b.target).parents("div."+h.blockMsgClass).length>0?!0:a(b.target).parents().children().filter("div.blockUI").length==0}function m(a){if(!g)return;var b=g[a===!0?g.length-1:0];b&&b.focus()}function n(a,b,c){var d=a.parentNode,e=a.style,f=(d.offsetWidth-a.offsetWidth)/2-o(d,"borderLeftWidth"),g=(d.offsetHeight-a.offsetHeight)/2-o(d,"borderTopWidth");b&&(e.left=f>0?f+"px":"0");c&&(e.top=g>0?g+"px":"0")}function o(b,c){return parseInt(a.css(b,c))||0}if(/1\.(0|1|2)\.(0|1|2)/.test(a.fn.jquery)||/^1.1/.test(a.fn.jquery)){alert("blockUI requires jQuery v1.2.3 or later! You are using v"+a.fn.jquery);return}a.fn._fadeIn=a.fn.fadeIn;var b=function(){},c=document.documentMode||0,d=a.browser.msie&&(a.browser.version<8&&!c||c<8),e=a.browser.msie&&/MSIE 6.0/.test(navigator.userAgent)&&!c;a.blockUI=function(a){h(window,a)};a.unblockUI=function(a){i(window,a)};a.growlUI=function(b,c,d,e){var f=a('<div class="growlUI"></div>');b&&f.append("<h1>"+b+"</h1>");c&&f.append("<h2>"+c+"</h2>");d==undefined&&(d=3e3);a.blockUI({message:f,fadeIn:700,fadeOut:1e3,centerY:!1,timeout:d,showOverlay:!1,onUnblock:e,css:a.blockUI.defaults.growlCSS})};a.fn.block=function(b){return this.unblock({fadeOut:0}).each(function(){a.css(this,"position")=="static"&&(this.style.position="relative");a.browser.msie&&(this.style.zoom=1);h(this,b)})};a.fn.unblock=function(a){return this.each(function(){i(this,a)})};a.blockUI.version=2.39;a.blockUI.defaults={message:"<h1>Please wait...</h1>",title:null,draggable:!0,theme:!1,css:{padding:0,margin:0,width:"30%",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"3px solid #aaa",backgroundColor:"#fff",cursor:"wait"},themedCSS:{width:"30%",top:"40%",left:"35%"},overlayCSS:{backgroundColor:"#000",opacity:.6,cursor:"wait"},growlCSS:{width:"350px",top:"10px",left:"",right:"10px",border:"none",padding:"5px",opacity:.6,cursor:"default",color:"#fff",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px","border-radius":"10px"},iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",forceIframe:!1,baseZ:1e3,centerX:!0,centerY:!0,allowBodyStretch:!0,bindEvents:!0,constrainTabKey:!0,fadeIn:200,fadeOut:400,timeout:0,showOverlay:!0,focusInput:!0,applyPlatformOpacityRules:!0,onBlock:null,onUnblock:null,quirksmodeOffsetHack:4,blockMsgClass:"blockMsg"};var f=null,g=[]})(jQuery);
|
assets/js/chosen/chosen-sprite.png
ADDED
Binary file
|
assets/js/chosen/chosen-sprite@2x.png
ADDED
Binary file
|
assets/js/chosen/chosen.css
ADDED
@@ -0,0 +1,413 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* @group Base */
|
2 |
+
.chzn-container {
|
3 |
+
font-size: 13px;
|
4 |
+
position: relative;
|
5 |
+
display: inline-block;
|
6 |
+
zoom: 1;
|
7 |
+
*display: inline;
|
8 |
+
}
|
9 |
+
.chzn-container .chzn-drop {
|
10 |
+
background: #fff;
|
11 |
+
border: 1px solid #aaa;
|
12 |
+
border-top: 0;
|
13 |
+
position: absolute;
|
14 |
+
top: 29px;
|
15 |
+
left: 0;
|
16 |
+
-webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15);
|
17 |
+
-moz-box-shadow : 0 4px 5px rgba(0,0,0,.15);
|
18 |
+
box-shadow : 0 4px 5px rgba(0,0,0,.15);
|
19 |
+
z-index: 1010;
|
20 |
+
}
|
21 |
+
/* @end */
|
22 |
+
|
23 |
+
/* @group Single Chosen */
|
24 |
+
.chzn-container-single .chzn-single {
|
25 |
+
background-color: #ffffff;
|
26 |
+
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0 );
|
27 |
+
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
|
28 |
+
background-image: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
29 |
+
background-image: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
30 |
+
background-image: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
31 |
+
background-image: linear-gradient(#ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
32 |
+
-webkit-border-radius: 5px;
|
33 |
+
-moz-border-radius : 5px;
|
34 |
+
border-radius : 5px;
|
35 |
+
-moz-background-clip : padding;
|
36 |
+
-webkit-background-clip: padding-box;
|
37 |
+
background-clip : padding-box;
|
38 |
+
border: 1px solid #aaaaaa;
|
39 |
+
-webkit-box-shadow: 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
|
40 |
+
-moz-box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
|
41 |
+
box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
|
42 |
+
display: block;
|
43 |
+
overflow: hidden;
|
44 |
+
white-space: nowrap;
|
45 |
+
position: relative;
|
46 |
+
height: 23px;
|
47 |
+
line-height: 24px;
|
48 |
+
padding: 0 0 0 8px;
|
49 |
+
color: #444444;
|
50 |
+
text-decoration: none;
|
51 |
+
}
|
52 |
+
.chzn-container-single .chzn-default {
|
53 |
+
color: #999;
|
54 |
+
}
|
55 |
+
.chzn-container-single .chzn-single span {
|
56 |
+
margin-right: 26px;
|
57 |
+
display: block;
|
58 |
+
overflow: hidden;
|
59 |
+
white-space: nowrap;
|
60 |
+
-o-text-overflow: ellipsis;
|
61 |
+
-ms-text-overflow: ellipsis;
|
62 |
+
text-overflow: ellipsis;
|
63 |
+
}
|
64 |
+
.chzn-container-single .chzn-single abbr {
|
65 |
+
display: block;
|
66 |
+
position: absolute;
|
67 |
+
right: 26px;
|
68 |
+
top: 6px;
|
69 |
+
width: 12px;
|
70 |
+
height: 12px;
|
71 |
+
font-size: 1px;
|
72 |
+
background: url('chosen-sprite.png') -42px 1px no-repeat;
|
73 |
+
}
|
74 |
+
.chzn-container-single .chzn-single abbr:hover {
|
75 |
+
background-position: -42px -10px;
|
76 |
+
}
|
77 |
+
.chzn-container-single.chzn-disabled .chzn-single abbr:hover {
|
78 |
+
background-position: -42px -10px;
|
79 |
+
}
|
80 |
+
.chzn-container-single .chzn-single div {
|
81 |
+
position: absolute;
|
82 |
+
right: 0;
|
83 |
+
top: 0;
|
84 |
+
display: block;
|
85 |
+
height: 100%;
|
86 |
+
width: 18px;
|
87 |
+
}
|
88 |
+
.chzn-container-single .chzn-single div b {
|
89 |
+
background: url('chosen-sprite.png') no-repeat 0px 2px;
|
90 |
+
display: block;
|
91 |
+
width: 100%;
|
92 |
+
height: 100%;
|
93 |
+
}
|
94 |
+
.chzn-container-single .chzn-search {
|
95 |
+
padding: 3px 4px;
|
96 |
+
position: relative;
|
97 |
+
margin: 0;
|
98 |
+
white-space: nowrap;
|
99 |
+
z-index: 1010;
|
100 |
+
}
|
101 |
+
.chzn-container-single .chzn-search input {
|
102 |
+
background: #fff url('chosen-sprite.png') no-repeat 100% -20px;
|
103 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
104 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
105 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
106 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
107 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
|
108 |
+
margin: 1px 0;
|
109 |
+
padding: 4px 20px 4px 5px;
|
110 |
+
outline: 0;
|
111 |
+
border: 1px solid #aaa;
|
112 |
+
font-family: sans-serif;
|
113 |
+
font-size: 1em;
|
114 |
+
}
|
115 |
+
.chzn-container-single .chzn-drop {
|
116 |
+
-webkit-border-radius: 0 0 4px 4px;
|
117 |
+
-moz-border-radius : 0 0 4px 4px;
|
118 |
+
border-radius : 0 0 4px 4px;
|
119 |
+
-moz-background-clip : padding;
|
120 |
+
-webkit-background-clip: padding-box;
|
121 |
+
background-clip : padding-box;
|
122 |
+
}
|
123 |
+
/* @end */
|
124 |
+
|
125 |
+
.chzn-container-single-nosearch .chzn-search input {
|
126 |
+
position: absolute;
|
127 |
+
left: -9000px;
|
128 |
+
}
|
129 |
+
|
130 |
+
/* @group Multi Chosen */
|
131 |
+
.chzn-container-multi .chzn-choices {
|
132 |
+
background-color: #fff;
|
133 |
+
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
134 |
+
background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
135 |
+
background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
136 |
+
background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
137 |
+
background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
|
138 |
+
border: 1px solid #aaa;
|
139 |
+
margin: 0;
|
140 |
+
padding: 0;
|
141 |
+
cursor: text;
|
142 |
+
overflow: hidden;
|
143 |
+
height: auto !important;
|
144 |
+
height: 1%;
|
145 |
+
position: relative;
|
146 |
+
}
|
147 |
+
.chzn-container-multi .chzn-choices li {
|
148 |
+
float: left;
|
149 |
+
list-style: none;
|
150 |
+
}
|
151 |
+
.chzn-container-multi .chzn-choices .search-field {
|
152 |
+
white-space: nowrap;
|
153 |
+
margin: 0;
|
154 |
+
padding: 0;
|
155 |
+
}
|
156 |
+
.chzn-container-multi .chzn-choices .search-field input {
|
157 |
+
color: #666;
|
158 |
+
background: transparent !important;
|
159 |
+
border: 0 !important;
|
160 |
+
font-family: sans-serif;
|
161 |
+
font-size: 100%;
|
162 |
+
height: 15px;
|
163 |
+
padding: 5px;
|
164 |
+
margin: 1px 0;
|
165 |
+
outline: 0;
|
166 |
+
-webkit-box-shadow: none;
|
167 |
+
-moz-box-shadow : none;
|
168 |
+
box-shadow : none;
|
169 |
+
}
|
170 |
+
.chzn-container-multi .chzn-choices .search-field .default {
|
171 |
+
color: #999;
|
172 |
+
}
|
173 |
+
.chzn-container-multi .chzn-choices .search-choice {
|
174 |
+
-webkit-border-radius: 3px;
|
175 |
+
-moz-border-radius : 3px;
|
176 |
+
border-radius : 3px;
|
177 |
+
-moz-background-clip : padding;
|
178 |
+
-webkit-background-clip: padding-box;
|
179 |
+
background-clip : padding-box;
|
180 |
+
background-color: #e4e4e4;
|
181 |
+
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 );
|
182 |
+
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
|
183 |
+
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
184 |
+
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
185 |
+
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
186 |
+
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
187 |
+
-webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
|
188 |
+
-moz-box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
|
189 |
+
box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
|
190 |
+
color: #333;
|
191 |
+
border: 1px solid #aaaaaa;
|
192 |
+
line-height: 13px;
|
193 |
+
padding: 3px 20px 3px 5px;
|
194 |
+
margin: 3px 0 3px 5px;
|
195 |
+
position: relative;
|
196 |
+
cursor: default;
|
197 |
+
}
|
198 |
+
.chzn-container-multi .chzn-choices .search-choice.search-choice-disabled {
|
199 |
+
background-color: #e4e4e4;
|
200 |
+
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 );
|
201 |
+
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
|
202 |
+
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
203 |
+
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
204 |
+
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
205 |
+
background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
206 |
+
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
207 |
+
color: #666;
|
208 |
+
border: 1px solid #cccccc;
|
209 |
+
padding-right: 5px;
|
210 |
+
}
|
211 |
+
.chzn-container-multi .chzn-choices .search-choice-focus {
|
212 |
+
background: #d4d4d4;
|
213 |
+
}
|
214 |
+
.chzn-container-multi .chzn-choices .search-choice .search-choice-close {
|
215 |
+
display: block;
|
216 |
+
position: absolute;
|
217 |
+
right: 3px;
|
218 |
+
top: 4px;
|
219 |
+
width: 12px;
|
220 |
+
height: 12px;
|
221 |
+
font-size: 1px;
|
222 |
+
background: url('chosen-sprite.png') -42px 1px no-repeat;
|
223 |
+
}
|
224 |
+
.chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover {
|
225 |
+
background-position: -42px -10px;
|
226 |
+
}
|
227 |
+
.chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close {
|
228 |
+
background-position: -42px -10px;
|
229 |
+
}
|
230 |
+
/* @end */
|
231 |
+
|
232 |
+
/* @group Results */
|
233 |
+
.chzn-container .chzn-results {
|
234 |
+
margin: 0 4px 4px 0;
|
235 |
+
max-height: 240px;
|
236 |
+
padding: 0 0 0 4px;
|
237 |
+
position: relative;
|
238 |
+
overflow-x: hidden;
|
239 |
+
overflow-y: auto;
|
240 |
+
-webkit-overflow-scrolling: touch;
|
241 |
+
}
|
242 |
+
.chzn-container-multi .chzn-results {
|
243 |
+
margin: -1px 0 0;
|
244 |
+
padding: 0;
|
245 |
+
}
|
246 |
+
.chzn-container .chzn-results li {
|
247 |
+
display: none;
|
248 |
+
line-height: 15px;
|
249 |
+
padding: 5px 6px;
|
250 |
+
margin: 0;
|
251 |
+
list-style: none;
|
252 |
+
}
|
253 |
+
.chzn-container .chzn-results .active-result {
|
254 |
+
cursor: pointer;
|
255 |
+
display: list-item;
|
256 |
+
}
|
257 |
+
.chzn-container .chzn-results .highlighted {
|
258 |
+
background-color: #3875d7;
|
259 |
+
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3875d7', endColorstr='#2a62bc', GradientType=0 );
|
260 |
+
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
|
261 |
+
background-image: -webkit-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
|
262 |
+
background-image: -moz-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
|
263 |
+
background-image: -o-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
|
264 |
+
background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
|
265 |
+
color: #fff;
|
266 |
+
}
|
267 |
+
.chzn-container .chzn-results li em {
|
268 |
+
background: #feffde;
|
269 |
+
font-style: normal;
|
270 |
+
}
|
271 |
+
.chzn-container .chzn-results .highlighted em {
|
272 |
+
background: transparent;
|
273 |
+
}
|
274 |
+
.chzn-container .chzn-results .no-results {
|
275 |
+
background: #f4f4f4;
|
276 |
+
display: list-item;
|
277 |
+
}
|
278 |
+
.chzn-container .chzn-results .group-result {
|
279 |
+
cursor: default;
|
280 |
+
color: #999;
|
281 |
+
font-weight: bold;
|
282 |
+
}
|
283 |
+
.chzn-container .chzn-results .group-option {
|
284 |
+
padding-left: 15px;
|
285 |
+
}
|
286 |
+
.chzn-container-multi .chzn-drop .result-selected {
|
287 |
+
display: none;
|
288 |
+
}
|
289 |
+
.chzn-container .chzn-results-scroll {
|
290 |
+
background: white;
|
291 |
+
margin: 0 4px;
|
292 |
+
position: absolute;
|
293 |
+
text-align: center;
|
294 |
+
width: 321px; /* This should by dynamic with js */
|
295 |
+
z-index: 1;
|
296 |
+
}
|
297 |
+
.chzn-container .chzn-results-scroll span {
|
298 |
+
display: inline-block;
|
299 |
+
height: 17px;
|
300 |
+
text-indent: -5000px;
|
301 |
+
width: 9px;
|
302 |
+
}
|
303 |
+
.chzn-container .chzn-results-scroll-down {
|
304 |
+
bottom: 0;
|
305 |
+
}
|
306 |
+
.chzn-container .chzn-results-scroll-down span {
|
307 |
+
background: url('chosen-sprite.png') no-repeat -4px -3px;
|
308 |
+
}
|
309 |
+
.chzn-container .chzn-results-scroll-up span {
|
310 |
+
background: url('chosen-sprite.png') no-repeat -22px -3px;
|
311 |
+
}
|
312 |
+
/* @end */
|
313 |
+
|
314 |
+
/* @group Active */
|
315 |
+
.chzn-container-active .chzn-single {
|
316 |
+
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
|
317 |
+
-moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
|
318 |
+
box-shadow : 0 0 5px rgba(0,0,0,.3);
|
319 |
+
border: 1px solid #5897fb;
|
320 |
+
}
|
321 |
+
.chzn-container-active .chzn-single-with-drop {
|
322 |
+
border: 1px solid #aaa;
|
323 |
+
-webkit-box-shadow: 0 1px 0 #fff inset;
|
324 |
+
-moz-box-shadow : 0 1px 0 #fff inset;
|
325 |
+
box-shadow : 0 1px 0 #fff inset;
|
326 |
+
background-color: #eee;
|
327 |
+
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0 );
|
328 |
+
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
|
329 |
+
background-image: -webkit-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
|
330 |
+
background-image: -moz-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
|
331 |
+
background-image: -o-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
|
332 |
+
background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
|
333 |
+
-webkit-border-bottom-left-radius : 0;
|
334 |
+
-webkit-border-bottom-right-radius: 0;
|
335 |
+
-moz-border-radius-bottomleft : 0;
|
336 |
+
-moz-border-radius-bottomright: 0;
|
337 |
+
border-bottom-left-radius : 0;
|
338 |
+
border-bottom-right-radius: 0;
|
339 |
+
}
|
340 |
+
.chzn-container-active .chzn-single-with-drop div {
|
341 |
+
background: transparent;
|
342 |
+
border-left: none;
|
343 |
+
}
|
344 |
+
.chzn-container-active .chzn-single-with-drop div b {
|
345 |
+
background-position: -18px 2px;
|
346 |
+
}
|
347 |
+
.chzn-container-active .chzn-choices {
|
348 |
+
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
|
349 |
+
-moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
|
350 |
+
box-shadow : 0 0 5px rgba(0,0,0,.3);
|
351 |
+
border: 1px solid #5897fb;
|
352 |
+
}
|
353 |
+
.chzn-container-active .chzn-choices .search-field input {
|
354 |
+
color: #111 !important;
|
355 |
+
}
|
356 |
+
/* @end */
|
357 |
+
|
358 |
+
/* @group Disabled Support */
|
359 |
+
.chzn-disabled {
|
360 |
+
cursor: default;
|
361 |
+
opacity:0.5 !important;
|
362 |
+
}
|
363 |
+
.chzn-disabled .chzn-single {
|
364 |
+
cursor: default;
|
365 |
+
}
|
366 |
+
.chzn-disabled .chzn-choices .search-choice .search-choice-close {
|
367 |
+
cursor: default;
|
368 |
+
}
|
369 |
+
|
370 |
+
/* @group Right to Left */
|
371 |
+
.chzn-rtl { text-align: right; }
|
372 |
+
.chzn-rtl .chzn-single { padding: 0 8px 0 0; overflow: visible; }
|
373 |
+
.chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; direction: rtl; }
|
374 |
+
|
375 |
+
.chzn-rtl .chzn-single div { left: 3px; right: auto; }
|
376 |
+
.chzn-rtl .chzn-single abbr {
|
377 |
+
left: 26px;
|
378 |
+
right: auto;
|
379 |
+
}
|
380 |
+
.chzn-rtl .chzn-choices .search-field input { direction: rtl; }
|
381 |
+
.chzn-rtl .chzn-choices li { float: right; }
|
382 |
+
.chzn-rtl .chzn-choices .search-choice { padding: 3px 5px 3px 19px; margin: 3px 5px 3px 0; }
|
383 |
+
.chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 4px; right: auto; }
|
384 |
+
.chzn-rtl.chzn-container-single .chzn-results { margin: 0 0 4px 4px; padding: 0 4px 0 0; }
|
385 |
+
.chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 15px; }
|
386 |
+
.chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; }
|
387 |
+
.chzn-rtl .chzn-search input {
|
388 |
+
background: #fff url('chosen-sprite.png') no-repeat -30px -20px;
|
389 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
390 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
391 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
392 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
|
393 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
|
394 |
+
padding: 4px 5px 4px 20px;
|
395 |
+
direction: rtl;
|
396 |
+
}
|
397 |
+
.chzn-container-single.chzn-rtl .chzn-single div b {
|
398 |
+
background-position: 6px 2px;
|
399 |
+
}
|
400 |
+
.chzn-container-single.chzn-rtl .chzn-single-with-drop div b {
|
401 |
+
background-position: -12px 2px;
|
402 |
+
}
|
403 |
+
/* @end */
|
404 |
+
|
405 |
+
/* @group Retina compatibility */
|
406 |
+
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
|
407 |
+
.chzn-rtl .chzn-search input, .chzn-container-single .chzn-single abbr, .chzn-container-single .chzn-single div b, .chzn-container-single .chzn-search input, .chzn-container-multi .chzn-choices .search-choice .search-choice-close, .chzn-container .chzn-results-scroll-down span, .chzn-container .chzn-results-scroll-up span {
|
408 |
+
background-image: url('chosen-sprite@2x.png') !important;
|
409 |
+
background-repeat: no-repeat !important;
|
410 |
+
background-size: 52px 37px !important;
|
411 |
+
}
|
412 |
+
}
|
413 |
+
/* @end */
|
assets/js/chosen/chosen.jquery.js
ADDED
@@ -0,0 +1,1090 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Chosen, a Select Box Enhancer for jQuery and Protoype
|
2 |
+
// by Patrick Filler for Harvest, http://getharvest.com
|
3 |
+
//
|
4 |
+
// Version 0.9.12
|
5 |
+
// Full source at https://github.com/harvesthq/chosen
|
6 |
+
// Copyright (c) 2011 Harvest http://getharvest.com
|
7 |
+
|
8 |
+
// MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
|
9 |
+
// This file is generated by `cake build`, do not edit it by hand.
|
10 |
+
(function() {
|
11 |
+
var SelectParser;
|
12 |
+
|
13 |
+
SelectParser = (function() {
|
14 |
+
|
15 |
+
function SelectParser() {
|
16 |
+
this.options_index = 0;
|
17 |
+
this.parsed = [];
|
18 |
+
}
|
19 |
+
|
20 |
+
SelectParser.prototype.add_node = function(child) {
|
21 |
+
if (child.nodeName.toUpperCase() === "OPTGROUP") {
|
22 |
+
return this.add_group(child);
|
23 |
+
} else {
|
24 |
+
return this.add_option(child);
|
25 |
+
}
|
26 |
+
};
|
27 |
+
|
28 |
+
SelectParser.prototype.add_group = function(group) {
|
29 |
+
var group_position, option, _i, _len, _ref, _results;
|
30 |
+
group_position = this.parsed.length;
|
31 |
+
this.parsed.push({
|
32 |
+
array_index: group_position,
|
33 |
+
group: true,
|
34 |
+
label: group.label,
|
35 |
+
children: 0,
|
36 |
+
disabled: group.disabled
|
37 |
+
});
|
38 |
+
_ref = group.childNodes;
|
39 |
+
_results = [];
|
40 |
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
41 |
+
option = _ref[_i];
|
42 |
+
_results.push(this.add_option(option, group_position, group.disabled));
|
43 |
+
}
|
44 |
+
return _results;
|
45 |
+
};
|
46 |
+
|
47 |
+
SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
|
48 |
+
if (option.nodeName.toUpperCase() === "OPTION") {
|
49 |
+
if (option.text !== "") {
|
50 |
+
if (group_position != null) {
|
51 |
+
this.parsed[group_position].children += 1;
|
52 |
+
}
|
53 |
+
this.parsed.push({
|
54 |
+
array_index: this.parsed.length,
|
55 |
+
options_index: this.options_index,
|
56 |
+
value: option.value,
|
57 |
+
text: option.text,
|
58 |
+
html: option.innerHTML,
|
59 |
+
selected: option.selected,
|
60 |
+
disabled: group_disabled === true ? group_disabled : option.disabled,
|
61 |
+
group_array_index: group_position,
|
62 |
+
classes: option.className,
|
63 |
+
style: option.style.cssText
|
64 |
+
});
|
65 |
+
} else {
|
66 |
+
this.parsed.push({
|
67 |
+
array_index: this.parsed.length,
|
68 |
+
options_index: this.options_index,
|
69 |
+
empty: true
|
70 |
+
});
|
71 |
+
}
|
72 |
+
return this.options_index += 1;
|
73 |
+
}
|
74 |
+
};
|
75 |
+
|
76 |
+
return SelectParser;
|
77 |
+
|
78 |
+
})();
|
79 |
+
|
80 |
+
SelectParser.select_to_array = function(select) {
|
81 |
+
var child, parser, _i, _len, _ref;
|
82 |
+
parser = new SelectParser();
|
83 |
+
_ref = select.childNodes;
|
84 |
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
85 |
+
child = _ref[_i];
|
86 |
+
parser.add_node(child);
|
87 |
+
}
|
88 |
+
return parser.parsed;
|
89 |
+
};
|
90 |
+
|
91 |
+
this.SelectParser = SelectParser;
|
92 |
+
|
93 |
+
}).call(this);
|
94 |
+
|
95 |
+
/*
|
96 |
+
Chosen source: generate output using 'cake build'
|
97 |
+
Copyright (c) 2011 by Harvest
|
98 |
+
*/
|
99 |
+
|
100 |
+
|
101 |
+
(function() {
|
102 |
+
var AbstractChosen, root;
|
103 |
+
|
104 |
+
root = this;
|
105 |
+
|
106 |
+
AbstractChosen = (function() {
|
107 |
+
|
108 |
+
function AbstractChosen(form_field, options) {
|
109 |
+
this.form_field = form_field;
|
110 |
+
this.options = options != null ? options : {};
|
111 |
+
this.is_multiple = this.form_field.multiple;
|
112 |
+
this.set_default_text();
|
113 |
+
this.set_default_values();
|
114 |
+
this.setup();
|
115 |
+
this.set_up_html();
|
116 |
+
this.register_observers();
|
117 |
+
this.finish_setup();
|
118 |
+
}
|
119 |
+
|
120 |
+
AbstractChosen.prototype.set_default_values = function() {
|
121 |
+
var _this = this;
|
122 |
+
this.click_test_action = function(evt) {
|
123 |
+
return _this.test_active_click(evt);
|
124 |
+
};
|
125 |
+
this.activate_action = function(evt) {
|
126 |
+
return _this.activate_field(evt);
|
127 |
+
};
|
128 |
+
this.active_field = false;
|
129 |
+
this.mouse_on_container = false;
|
130 |
+
this.results_showing = false;
|
131 |
+
this.result_highlighted = null;
|
132 |
+
this.result_single_selected = null;
|
133 |
+
this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
|
134 |
+
this.disable_search_threshold = this.options.disable_search_threshold || 0;
|
135 |
+
this.disable_search = this.options.disable_search || false;
|
136 |
+
this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
|
137 |
+
this.search_contains = this.options.search_contains || false;
|
138 |
+
this.choices = 0;
|
139 |
+
this.single_backstroke_delete = this.options.single_backstroke_delete || false;
|
140 |
+
this.max_selected_options = this.options.max_selected_options || Infinity;
|
141 |
+
return this.inherit_select_classes = this.options.inherit_select_classes || false;
|
142 |
+
};
|
143 |
+
|
144 |
+
AbstractChosen.prototype.set_default_text = function() {
|
145 |
+
if (this.form_field.getAttribute("data-placeholder")) {
|
146 |
+
this.default_text = this.form_field.getAttribute("data-placeholder");
|
147 |
+
} else if (this.is_multiple) {
|
148 |
+
this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || "Select Some Options";
|
149 |
+
} else {
|
150 |
+
this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || "Select an Option";
|
151 |
+
}
|
152 |
+
return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || "No results match";
|
153 |
+
};
|
154 |
+
|
155 |
+
AbstractChosen.prototype.mouse_enter = function() {
|
156 |
+
return this.mouse_on_container = true;
|
157 |
+
};
|
158 |
+
|
159 |
+
AbstractChosen.prototype.mouse_leave = function() {
|
160 |
+
return this.mouse_on_container = false;
|
161 |
+
};
|
162 |
+
|
163 |
+
AbstractChosen.prototype.input_focus = function(evt) {
|
164 |
+
var _this = this;
|
165 |
+
if (this.is_multiple) {
|
166 |
+
if (!this.active_field) {
|
167 |
+
return setTimeout((function() {
|
168 |
+
return _this.container_mousedown();
|
169 |
+
}), 50);
|
170 |
+
}
|
171 |
+
} else {
|
172 |
+
if (!this.active_field) {
|
173 |
+
return this.activate_field();
|
174 |
+
}
|
175 |
+
}
|
176 |
+
};
|
177 |
+
|
178 |
+
AbstractChosen.prototype.input_blur = function(evt) {
|
179 |
+
var _this = this;
|
180 |
+
if (!this.mouse_on_container) {
|
181 |
+
this.active_field = false;
|
182 |
+
return setTimeout((function() {
|
183 |
+
return _this.blur_test();
|
184 |
+
}), 100);
|
185 |
+
}
|
186 |
+
};
|
187 |
+
|
188 |
+
AbstractChosen.prototype.result_add_option = function(option) {
|
189 |
+
var classes, style;
|
190 |
+
if (!option.disabled) {
|
191 |
+
option.dom_id = this.container_id + "_o_" + option.array_index;
|
192 |
+
classes = option.selected && this.is_multiple ? [] : ["active-result"];
|
193 |
+
if (option.selected) {
|
194 |
+
classes.push("result-selected");
|
195 |
+
}
|
196 |
+
if (option.group_array_index != null) {
|
197 |
+
classes.push("group-option");
|
198 |
+
}
|
199 |
+
if (option.classes !== "") {
|
200 |
+
classes.push(option.classes);
|
201 |
+
}
|
202 |
+
style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : "";
|
203 |
+
return '<li id="' + option.dom_id + '" class="' + classes.join(' ') + '"' + style + '>' + option.html + '</li>';
|
204 |
+
} else {
|
205 |
+
return "";
|
206 |
+
}
|
207 |
+
};
|
208 |
+
|
209 |
+
AbstractChosen.prototype.results_update_field = function() {
|
210 |
+
this.set_default_text();
|
211 |
+
if (!this.is_multiple) {
|
212 |
+
this.results_reset_cleanup();
|
213 |
+
}
|
214 |
+
this.result_clear_highlight();
|
215 |
+
this.result_single_selected = null;
|
216 |
+
return this.results_build();
|
217 |
+
};
|
218 |
+
|
219 |
+
AbstractChosen.prototype.results_toggle = function() {
|
220 |
+
if (this.results_showing) {
|
221 |
+
return this.results_hide();
|
222 |
+
} else {
|
223 |
+
return this.results_show();
|
224 |
+
}
|
225 |
+
};
|
226 |
+
|
227 |
+
AbstractChosen.prototype.results_search = function(evt) {
|
228 |
+
if (this.results_showing) {
|
229 |
+
return this.winnow_results();
|
230 |
+
} else {
|
231 |
+
return this.results_show();
|
232 |
+
}
|
233 |
+
};
|
234 |
+
|
235 |
+
AbstractChosen.prototype.keyup_checker = function(evt) {
|
236 |
+
var stroke, _ref;
|
237 |
+
stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
|
238 |
+
this.search_field_scale();
|
239 |
+
switch (stroke) {
|
240 |
+
case 8:
|
241 |
+
if (this.is_multiple && this.backstroke_length < 1 && this.choices > 0) {
|
242 |
+
return this.keydown_backstroke();
|
243 |
+
} else if (!this.pending_backstroke) {
|
244 |
+
this.result_clear_highlight();
|
245 |
+
return this.results_search();
|
246 |
+
}
|
247 |
+
break;
|
248 |
+
case 13:
|
249 |
+
evt.preventDefault();
|
250 |
+
if (this.results_showing) {
|
251 |
+
return this.result_select(evt);
|
252 |
+
}
|
253 |
+
break;
|
254 |
+
case 27:
|
255 |
+
if (this.results_showing) {
|
256 |
+
this.results_hide();
|
257 |
+
}
|
258 |
+
return true;
|
259 |
+
case 9:
|
260 |
+
case 38:
|
261 |
+
case 40:
|
262 |
+
case 16:
|
263 |
+
case 91:
|
264 |
+
case 17:
|
265 |
+
break;
|
266 |
+
default:
|
267 |
+
return this.results_search();
|
268 |
+
}
|
269 |
+
};
|
270 |
+
|
271 |
+
AbstractChosen.prototype.generate_field_id = function() {
|
272 |
+
var new_id;
|
273 |
+
new_id = this.generate_random_id();
|
274 |
+
this.form_field.id = new_id;
|
275 |
+
return new_id;
|
276 |
+
};
|
277 |
+
|
278 |
+
AbstractChosen.prototype.generate_random_char = function() {
|
279 |
+
var chars, newchar, rand;
|
280 |
+
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
281 |
+
rand = Math.floor(Math.random() * chars.length);
|
282 |
+
return newchar = chars.substring(rand, rand + 1);
|
283 |
+
};
|
284 |
+
|
285 |
+
return AbstractChosen;
|
286 |
+
|
287 |
+
})();
|
288 |
+
|
289 |
+
root.AbstractChosen = AbstractChosen;
|
290 |
+
|
291 |
+
}).call(this);
|
292 |
+
|
293 |
+
/*
|
294 |
+
Chosen source: generate output using 'cake build'
|
295 |
+
Copyright (c) 2011 by Harvest
|
296 |
+
*/
|
297 |
+
|
298 |
+
|
299 |
+
(function() {
|
300 |
+
var $, Chosen, get_side_border_padding, root,
|
301 |
+
__hasProp = {}.hasOwnProperty,
|
302 |
+
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
303 |
+
|
304 |
+
root = this;
|
305 |
+
|
306 |
+
$ = jQuery;
|
307 |
+
|
308 |
+
$.fn.extend({
|
309 |
+
chosen: function(options) {
|
310 |
+
var browser, match, ua;
|
311 |
+
ua = navigator.userAgent.toLowerCase();
|
312 |
+
match = /(msie) ([\w.]+)/.exec(ua) || [];
|
313 |
+
browser = {
|
314 |
+
name: match[1] || "",
|
315 |
+
version: match[2] || "0"
|
316 |
+
};
|
317 |
+
if (browser.name === "msie" && (browser.version === "6.0" || (browser.version === "7.0" && document.documentMode === 7))) {
|
318 |
+
return this;
|
319 |
+
}
|
320 |
+
return this.each(function(input_field) {
|
321 |
+
var $this;
|
322 |
+
$this = $(this);
|
323 |
+
if (!$this.hasClass("chzn-done")) {
|
324 |
+
return $this.data('chosen', new Chosen(this, options));
|
325 |
+
}
|
326 |
+
});
|
327 |
+
}
|
328 |
+
});
|
329 |
+
|
330 |
+
Chosen = (function(_super) {
|
331 |
+
|
332 |
+
__extends(Chosen, _super);
|
333 |
+
|
334 |
+
function Chosen() {
|
335 |
+
return Chosen.__super__.constructor.apply(this, arguments);
|
336 |
+
}
|
337 |
+
|
338 |
+
Chosen.prototype.setup = function() {
|
339 |
+
this.form_field_jq = $(this.form_field);
|
340 |
+
this.current_value = this.form_field_jq.val();
|
341 |
+
return this.is_rtl = this.form_field_jq.hasClass("chzn-rtl");
|
342 |
+
};
|
343 |
+
|
344 |
+
Chosen.prototype.finish_setup = function() {
|
345 |
+
return this.form_field_jq.addClass("chzn-done");
|
346 |
+
};
|
347 |
+
|
348 |
+
Chosen.prototype.set_up_html = function() {
|
349 |
+
var container_classes, container_div, container_props, dd_top, dd_width, sf_width;
|
350 |
+
this.container_id = this.form_field.id.length ? this.form_field.id.replace(/[^\w]/g, '_') : this.generate_field_id();
|
351 |
+
this.container_id += "_chzn";
|
352 |
+
container_classes = ["chzn-container"];
|
353 |
+
container_classes.push("chzn-container-" + (this.is_multiple ? "multi" : "single"));
|
354 |
+
if (this.inherit_select_classes && this.form_field.className) {
|
355 |
+
container_classes.push(this.form_field.className);
|
356 |
+
}
|
357 |
+
if (this.is_rtl) {
|
358 |
+
container_classes.push("chzn-rtl");
|
359 |
+
}
|
360 |
+
this.f_width = this.form_field_jq.outerWidth();
|
361 |
+
container_props = {
|
362 |
+
id: this.container_id,
|
363 |
+
"class": container_classes.join(' '),
|
364 |
+
style: 'width: ' + this.f_width + 'px;',
|
365 |
+
title: this.form_field.title
|
366 |
+
};
|
367 |
+
container_div = $("<div />", container_props);
|
368 |
+
if (this.is_multiple) {
|
369 |
+
container_div.html('<ul class="chzn-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>');
|
370 |
+
} else {
|
371 |
+
container_div.html('<a href="javascript:void(0)" class="chzn-single chzn-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>');
|
372 |
+
}
|
373 |
+
this.form_field_jq.hide().after(container_div);
|
374 |
+
this.container = $('#' + this.container_id);
|
375 |
+
this.dropdown = this.container.find('div.chzn-drop').first();
|
376 |
+
dd_top = this.container.height();
|
377 |
+
dd_width = this.f_width - get_side_border_padding(this.dropdown);
|
378 |
+
this.dropdown.css({
|
379 |
+
"width": dd_width + "px",
|
380 |
+
"top": dd_top + "px"
|
381 |
+
});
|
382 |
+
this.search_field = this.container.find('input').first();
|
383 |
+
this.search_results = this.container.find('ul.chzn-results').first();
|
384 |
+
this.search_field_scale();
|
385 |
+
this.search_no_results = this.container.find('li.no-results').first();
|
386 |
+
if (this.is_multiple) {
|
387 |
+
this.search_choices = this.container.find('ul.chzn-choices').first();
|
388 |
+
this.search_container = this.container.find('li.search-field').first();
|
389 |
+
} else {
|
390 |
+
this.search_container = this.container.find('div.chzn-search').first();
|
391 |
+
this.selected_item = this.container.find('.chzn-single').first();
|
392 |
+
sf_width = dd_width - get_side_border_padding(this.search_container) - get_side_border_padding(this.search_field);
|
393 |
+
this.search_field.css({
|
394 |
+
"width": sf_width + "px"
|
395 |
+
});
|
396 |
+
}
|
397 |
+
this.results_build();
|
398 |
+
this.set_tab_index();
|
399 |
+
return this.form_field_jq.trigger("liszt:ready", {
|
400 |
+
chosen: this
|
401 |
+
});
|
402 |
+
};
|
403 |
+
|
404 |
+
Chosen.prototype.register_observers = function() {
|
405 |
+
var _this = this;
|
406 |
+
this.container.mousedown(function(evt) {
|
407 |
+
_this.container_mousedown(evt);
|
408 |
+
});
|
409 |
+
this.container.mouseup(function(evt) {
|
410 |
+
_this.container_mouseup(evt);
|
411 |
+
});
|
412 |
+
this.container.mouseenter(function(evt) {
|
413 |
+
_this.mouse_enter(evt);
|
414 |
+
});
|
415 |
+
this.container.mouseleave(function(evt) {
|
416 |
+
_this.mouse_leave(evt);
|
417 |
+
});
|
418 |
+
this.search_results.mouseup(function(evt) {
|
419 |
+
_this.search_results_mouseup(evt);
|
420 |
+
});
|
421 |
+
this.search_results.mouseover(function(evt) {
|
422 |
+
_this.search_results_mouseover(evt);
|
423 |
+
});
|
424 |
+
this.search_results.mouseout(function(evt) {
|
425 |
+
_this.search_results_mouseout(evt);
|
426 |
+
});
|
427 |
+
this.form_field_jq.bind("liszt:updated", function(evt) {
|
428 |
+
_this.results_update_field(evt);
|
429 |
+
});
|
430 |
+
this.form_field_jq.bind("liszt:activate", function(evt) {
|
431 |
+
_this.activate_field(evt);
|
432 |
+
});
|
433 |
+
this.form_field_jq.bind("liszt:open", function(evt) {
|
434 |
+
_this.container_mousedown(evt);
|
435 |
+
});
|
436 |
+
this.search_field.blur(function(evt) {
|
437 |
+
_this.input_blur(evt);
|
438 |
+
});
|
439 |
+
this.search_field.keyup(function(evt) {
|
440 |
+
_this.keyup_checker(evt);
|
441 |
+
});
|
442 |
+
this.search_field.keydown(function(evt) {
|
443 |
+
_this.keydown_checker(evt);
|
444 |
+
});
|
445 |
+
this.search_field.focus(function(evt) {
|
446 |
+
_this.input_focus(evt);
|
447 |
+
});
|
448 |
+
if (this.is_multiple) {
|
449 |
+
return this.search_choices.click(function(evt) {
|
450 |
+
_this.choices_click(evt);
|
451 |
+
});
|
452 |
+
} else {
|
453 |
+
return this.container.click(function(evt) {
|
454 |
+
evt.preventDefault();
|
455 |
+
});
|
456 |
+
}
|
457 |
+
};
|
458 |
+
|
459 |
+
Chosen.prototype.search_field_disabled = function() {
|
460 |
+
this.is_disabled = this.form_field_jq[0].disabled;
|
461 |
+
if (this.is_disabled) {
|
462 |
+
this.container.addClass('chzn-disabled');
|
463 |
+
this.search_field[0].disabled = true;
|
464 |
+
if (!this.is_multiple) {
|
465 |
+
this.selected_item.unbind("focus", this.activate_action);
|
466 |
+
}
|
467 |
+
return this.close_field();
|
468 |
+
} else {
|
469 |
+
this.container.removeClass('chzn-disabled');
|
470 |
+
this.search_field[0].disabled = false;
|
471 |
+
if (!this.is_multiple) {
|
472 |
+
return this.selected_item.bind("focus", this.activate_action);
|
473 |
+
}
|
474 |
+
}
|
475 |
+
};
|
476 |
+
|
477 |
+
Chosen.prototype.container_mousedown = function(evt) {
|
478 |
+
var target_closelink;
|
479 |
+
if (!this.is_disabled) {
|
480 |
+
target_closelink = evt != null ? ($(evt.target)).hasClass("search-choice-close") : false;
|
481 |
+
if (evt && evt.type === "mousedown" && !this.results_showing) {
|
482 |
+
evt.preventDefault();
|
483 |
+
}
|
484 |
+
if (!this.pending_destroy_click && !target_closelink) {
|
485 |
+
if (!this.active_field) {
|
486 |
+
if (this.is_multiple) {
|
487 |
+
this.search_field.val("");
|
488 |
+
}
|
489 |
+
$(document).click(this.click_test_action);
|
490 |
+
this.results_show();
|
491 |
+
} else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chzn-single").length)) {
|
492 |
+
evt.preventDefault();
|
493 |
+
this.results_toggle();
|
494 |
+
}
|
495 |
+
return this.activate_field();
|
496 |
+
} else {
|
497 |
+
return this.pending_destroy_click = false;
|
498 |
+
}
|
499 |
+
}
|
500 |
+
};
|
501 |
+
|
502 |
+
Chosen.prototype.container_mouseup = function(evt) {
|
503 |
+
if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
|
504 |
+
return this.results_reset(evt);
|
505 |
+
}
|
506 |
+
};
|
507 |
+
|
508 |
+
Chosen.prototype.blur_test = function(evt) {
|
509 |
+
if (!this.active_field && this.container.hasClass("chzn-container-active")) {
|
510 |
+
return this.close_field();
|
511 |
+
}
|
512 |
+
};
|
513 |
+
|
514 |
+
Chosen.prototype.close_field = function() {
|
515 |
+
$(document).unbind("click", this.click_test_action);
|
516 |
+
this.active_field = false;
|
517 |
+
this.results_hide();
|
518 |
+
this.container.removeClass("chzn-container-active");
|
519 |
+
this.winnow_results_clear();
|
520 |
+
this.clear_backstroke();
|
521 |
+
this.show_search_field_default();
|
522 |
+
return this.search_field_scale();
|
523 |
+
};
|
524 |
+
|
525 |
+
Chosen.prototype.activate_field = function() {
|
526 |
+
this.container.addClass("chzn-container-active");
|
527 |
+
this.active_field = true;
|
528 |
+
this.search_field.val(this.search_field.val());
|
529 |
+
return this.search_field.focus();
|
530 |
+
};
|
531 |
+
|
532 |
+
Chosen.prototype.test_active_click = function(evt) {
|
533 |
+
if ($(evt.target).parents('#' + this.container_id).length) {
|
534 |
+
return this.active_field = true;
|
535 |
+
} else {
|
536 |
+
return this.close_field();
|
537 |
+
}
|
538 |
+
};
|
539 |
+
|
540 |
+
Chosen.prototype.results_build = function() {
|
541 |
+
var content, data, _i, _len, _ref;
|
542 |
+
this.parsing = true;
|
543 |
+
this.results_data = root.SelectParser.select_to_array(this.form_field);
|
544 |
+
if (this.is_multiple && this.choices > 0) {
|
545 |
+
this.search_choices.find("li.search-choice").remove();
|
546 |
+
this.choices = 0;
|
547 |
+
} else if (!this.is_multiple) {
|
548 |
+
this.selected_item.addClass("chzn-default").find("span").text(this.default_text);
|
549 |
+
if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
|
550 |
+
this.container.addClass("chzn-container-single-nosearch");
|
551 |
+
} else {
|
552 |
+
this.container.removeClass("chzn-container-single-nosearch");
|
553 |
+
}
|
554 |
+
}
|
555 |
+
content = '';
|
556 |
+
_ref = this.results_data;
|
557 |
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
558 |
+
data = _ref[_i];
|
559 |
+
if (data.group) {
|
560 |
+
content += this.result_add_group(data);
|
561 |
+
} else if (!data.empty) {
|
562 |
+
content += this.result_add_option(data);
|
563 |
+
if (data.selected && this.is_multiple) {
|
564 |
+
this.choice_build(data);
|
565 |
+
} else if (data.selected && !this.is_multiple) {
|
566 |
+
this.selected_item.removeClass("chzn-default").find("span").text(data.text);
|
567 |
+
if (this.allow_single_deselect) {
|
568 |
+
this.single_deselect_control_build();
|
569 |
+
}
|
570 |
+
}
|
571 |
+
}
|
572 |
+
}
|
573 |
+
this.search_field_disabled();
|
574 |
+
this.show_search_field_default();
|
575 |
+
this.search_field_scale();
|
576 |
+
this.search_results.html(content);
|
577 |
+
return this.parsing = false;
|
578 |
+
};
|
579 |
+
|
580 |
+
Chosen.prototype.result_add_group = function(group) {
|
581 |
+
if (!group.disabled) {
|
582 |
+
group.dom_id = this.container_id + "_g_" + group.array_index;
|
583 |
+
return '<li id="' + group.dom_id + '" class="group-result">' + $("<div />").text(group.label).html() + '</li>';
|
584 |
+
} else {
|
585 |
+
return "";
|
586 |
+
}
|
587 |
+
};
|
588 |
+
|
589 |
+
Chosen.prototype.result_do_highlight = function(el) {
|
590 |
+
var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
|
591 |
+
if (el.length) {
|
592 |
+
this.result_clear_highlight();
|
593 |
+
this.result_highlight = el;
|
594 |
+
this.result_highlight.addClass("highlighted");
|
595 |
+
maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
|
596 |
+
visible_top = this.search_results.scrollTop();
|
597 |
+
visible_bottom = maxHeight + visible_top;
|
598 |
+
high_top = this.result_highlight.position().top + this.search_results.scrollTop();
|
599 |
+
high_bottom = high_top + this.result_highlight.outerHeight();
|
600 |
+
if (high_bottom >= visible_bottom) {
|
601 |
+
return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
|
602 |
+
} else if (high_top < visible_top) {
|
603 |
+
return this.search_results.scrollTop(high_top);
|
604 |
+
}
|
605 |
+
}
|
606 |
+
};
|
607 |
+
|
608 |
+
Chosen.prototype.result_clear_highlight = function() {
|
609 |
+
if (this.result_highlight) {
|
610 |
+
this.result_highlight.removeClass("highlighted");
|
611 |
+
}
|
612 |
+
return this.result_highlight = null;
|
613 |
+
};
|
614 |
+
|
615 |
+
Chosen.prototype.results_show = function() {
|
616 |
+
var dd_top;
|
617 |
+
if (!this.is_multiple) {
|
618 |
+
this.selected_item.addClass("chzn-single-with-drop");
|
619 |
+
if (this.result_single_selected) {
|
620 |
+
this.result_do_highlight(this.result_single_selected);
|
621 |
+
}
|
622 |
+
} else if (this.max_selected_options <= this.choices) {
|
623 |
+
this.form_field_jq.trigger("liszt:maxselected", {
|
624 |
+
chosen: this
|
625 |
+
});
|
626 |
+
return false;
|
627 |
+
}
|
628 |
+
dd_top = this.is_multiple ? this.container.height() : this.container.height() - 1;
|
629 |
+
this.form_field_jq.trigger("liszt:showing_dropdown", {
|
630 |
+
chosen: this
|
631 |
+
});
|
632 |
+
this.dropdown.css({
|
633 |
+
"top": dd_top + "px",
|
634 |
+
"left": 0
|
635 |
+
});
|
636 |
+
this.results_showing = true;
|
637 |
+
this.search_field.focus();
|
638 |
+
this.search_field.val(this.search_field.val());
|
639 |
+
return this.winnow_results();
|
640 |
+
};
|
641 |
+
|
642 |
+
Chosen.prototype.results_hide = function() {
|
643 |
+
if (!this.is_multiple) {
|
644 |
+
this.selected_item.removeClass("chzn-single-with-drop");
|
645 |
+
}
|
646 |
+
this.result_clear_highlight();
|
647 |
+
this.form_field_jq.trigger("liszt:hiding_dropdown", {
|
648 |
+
chosen: this
|
649 |
+
});
|
650 |
+
this.dropdown.css({
|
651 |
+
"left": "-9000px"
|
652 |
+
});
|
653 |
+
return this.results_showing = false;
|
654 |
+
};
|
655 |
+
|
656 |
+
Chosen.prototype.set_tab_index = function(el) {
|
657 |
+
var ti;
|
658 |
+
if (this.form_field_jq.attr("tabindex")) {
|
659 |
+
ti = this.form_field_jq.attr("tabindex");
|
660 |
+
this.form_field_jq.attr("tabindex", -1);
|
661 |
+
return this.search_field.attr("tabindex", ti);
|
662 |
+
}
|
663 |
+
};
|
664 |
+
|
665 |
+
Chosen.prototype.show_search_field_default = function() {
|
666 |
+
if (this.is_multiple && this.choices < 1 && !this.active_field) {
|
667 |
+
this.search_field.val(this.default_text);
|
668 |
+
return this.search_field.addClass("default");
|
669 |
+
} else {
|
670 |
+
this.search_field.val("");
|
671 |
+
return this.search_field.removeClass("default");
|
672 |
+
}
|
673 |
+
};
|
674 |
+
|
675 |
+
Chosen.prototype.search_results_mouseup = function(evt) {
|
676 |
+
var target;
|
677 |
+
target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
|
678 |
+
if (target.length) {
|
679 |
+
this.result_highlight = target;
|
680 |
+
this.result_select(evt);
|
681 |
+
return this.search_field.focus();
|
682 |
+
}
|
683 |
+
};
|
684 |
+
|
685 |
+
Chosen.prototype.search_results_mouseover = function(evt) {
|
686 |
+
var target;
|
687 |
+
target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
|
688 |
+
if (target) {
|
689 |
+
return this.result_do_highlight(target);
|
690 |
+
}
|
691 |
+
};
|
692 |
+
|
693 |
+
Chosen.prototype.search_results_mouseout = function(evt) {
|
694 |
+
if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
|
695 |
+
return this.result_clear_highlight();
|
696 |
+
}
|
697 |
+
};
|
698 |
+
|
699 |
+
Chosen.prototype.choices_click = function(evt) {
|
700 |
+
evt.preventDefault();
|
701 |
+
if (this.active_field && !($(evt.target).hasClass("search-choice" || $(evt.target).parents('.search-choice').first)) && !this.results_showing) {
|
702 |
+
return this.results_show();
|
703 |
+
}
|
704 |
+
};
|
705 |
+
|
706 |
+
Chosen.prototype.choice_build = function(item) {
|
707 |
+
var choice_id, html, link,
|
708 |
+
_this = this;
|
709 |
+
if (this.is_multiple && this.max_selected_options <= this.choices) {
|
710 |
+
this.form_field_jq.trigger("liszt:maxselected", {
|
711 |
+
chosen: this
|
712 |
+
});
|
713 |
+
return false;
|
714 |
+
}
|
715 |
+
choice_id = this.container_id + "_c_" + item.array_index;
|
716 |
+
this.choices += 1;
|
717 |
+
if (item.disabled) {
|
718 |
+
html = '<li class="search-choice search-choice-disabled" id="' + choice_id + '"><span>' + item.html + '</span></li>';
|
719 |
+
} else {
|
720 |
+
html = '<li class="search-choice" id="' + choice_id + '"><span>' + item.html + '</span><a href="javascript:void(0)" class="search-choice-close" rel="' + item.array_index + '"></a></li>';
|
721 |
+
}
|
722 |
+
this.search_container.before(html);
|
723 |
+
link = $('#' + choice_id).find("a").first();
|
724 |
+
return link.click(function(evt) {
|
725 |
+
return _this.choice_destroy_link_click(evt);
|
726 |
+
});
|
727 |
+
};
|
728 |
+
|
729 |
+
Chosen.prototype.choice_destroy_link_click = function(evt) {
|
730 |
+
evt.preventDefault();
|
731 |
+
if (!this.is_disabled) {
|
732 |
+
this.pending_destroy_click = true;
|
733 |
+
return this.choice_destroy($(evt.target));
|
734 |
+
} else {
|
735 |
+
return evt.stopPropagation;
|
736 |
+
}
|
737 |
+
};
|
738 |
+
|
739 |
+
Chosen.prototype.choice_destroy = function(link) {
|
740 |
+
if (this.result_deselect(link.attr("rel"))) {
|
741 |
+
this.choices -= 1;
|
742 |
+
this.show_search_field_default();
|
743 |
+
if (this.is_multiple && this.choices > 0 && this.search_field.val().length < 1) {
|
744 |
+
this.results_hide();
|
745 |
+
}
|
746 |
+
link.parents('li').first().remove();
|
747 |
+
return this.search_field_scale();
|
748 |
+
}
|
749 |
+
};
|
750 |
+
|
751 |
+
Chosen.prototype.results_reset = function() {
|
752 |
+
this.form_field.options[0].selected = true;
|
753 |
+
this.selected_item.find("span").text(this.default_text);
|
754 |
+
if (!this.is_multiple) {
|
755 |
+
this.selected_item.addClass("chzn-default");
|
756 |
+
}
|
757 |
+
this.show_search_field_default();
|
758 |
+
this.results_reset_cleanup();
|
759 |
+
this.form_field_jq.trigger("change");
|
760 |
+
if (this.active_field) {
|
761 |
+
return this.results_hide();
|
762 |
+
}
|
763 |
+
};
|
764 |
+
|
765 |
+
Chosen.prototype.results_reset_cleanup = function() {
|
766 |
+
this.current_value = this.form_field_jq.val();
|
767 |
+
return this.selected_item.find("abbr").remove();
|
768 |
+
};
|
769 |
+
|
770 |
+
Chosen.prototype.result_select = function(evt) {
|
771 |
+
var high, high_id, item, position;
|
772 |
+
if (this.result_highlight) {
|
773 |
+
high = this.result_highlight;
|
774 |
+
high_id = high.attr("id");
|
775 |
+
this.result_clear_highlight();
|
776 |
+
if (this.is_multiple) {
|
777 |
+
this.result_deactivate(high);
|
778 |
+
} else {
|
779 |
+
this.search_results.find(".result-selected").removeClass("result-selected");
|
780 |
+
this.result_single_selected = high;
|
781 |
+
this.selected_item.removeClass("chzn-default");
|
782 |
+
}
|
783 |
+
high.addClass("result-selected");
|
784 |
+
position = high_id.substr(high_id.lastIndexOf("_") + 1);
|
785 |
+
item = this.results_data[position];
|
786 |
+
item.selected = true;
|
787 |
+
this.form_field.options[item.options_index].selected = true;
|
788 |
+
if (this.is_multiple) {
|
789 |
+
this.choice_build(item);
|
790 |
+
} else {
|
791 |
+
this.selected_item.find("span").first().text(item.text);
|
792 |
+
if (this.allow_single_deselect) {
|
793 |
+
this.single_deselect_control_build();
|
794 |
+
}
|
795 |
+
}
|
796 |
+
if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
|
797 |
+
this.results_hide();
|
798 |
+
}
|
799 |
+
this.search_field.val("");
|
800 |
+
if (this.is_multiple || this.form_field_jq.val() !== this.current_value) {
|
801 |
+
this.form_field_jq.trigger("change", {
|
802 |
+
'selected': this.form_field.options[item.options_index].value
|
803 |
+
});
|
804 |
+
}
|
805 |
+
this.current_value = this.form_field_jq.val();
|
806 |
+
return this.search_field_scale();
|
807 |
+
}
|
808 |
+
};
|
809 |
+
|
810 |
+
Chosen.prototype.result_activate = function(el) {
|
811 |
+
return el.addClass("active-result");
|
812 |
+
};
|
813 |
+
|
814 |
+
Chosen.prototype.result_deactivate = function(el) {
|
815 |
+
return el.removeClass("active-result");
|
816 |
+
};
|
817 |
+
|
818 |
+
Chosen.prototype.result_deselect = function(pos) {
|
819 |
+
var result, result_data;
|
820 |
+
result_data = this.results_data[pos];
|
821 |
+
if (!this.form_field.options[result_data.options_index].disabled) {
|
822 |
+
result_data.selected = false;
|
823 |
+
this.form_field.options[result_data.options_index].selected = false;
|
824 |
+
result = $("#" + this.container_id + "_o_" + pos);
|
825 |
+
result.removeClass("result-selected").addClass("active-result").show();
|
826 |
+
this.result_clear_highlight();
|
827 |
+
this.winnow_results();
|
828 |
+
this.form_field_jq.trigger("change", {
|
829 |
+
deselected: this.form_field.options[result_data.options_index].value
|
830 |
+
});
|
831 |
+
this.search_field_scale();
|
832 |
+
return true;
|
833 |
+
} else {
|
834 |
+
return false;
|
835 |
+
}
|
836 |
+
};
|
837 |
+
|
838 |
+
Chosen.prototype.single_deselect_control_build = function() {
|
839 |
+
if (this.allow_single_deselect && this.selected_item.find("abbr").length < 1) {
|
840 |
+
return this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
|
841 |
+
}
|
842 |
+
};
|
843 |
+
|
844 |
+
Chosen.prototype.winnow_results = function() {
|
845 |
+
var found, option, part, parts, regex, regexAnchor, result, result_id, results, searchText, startpos, text, zregex, _i, _j, _len, _len1, _ref;
|
846 |
+
this.no_results_clear();
|
847 |
+
results = 0;
|
848 |
+
searchText = this.search_field.val() === this.default_text ? "" : $('<div/>').text($.trim(this.search_field.val())).html();
|
849 |
+
regexAnchor = this.search_contains ? "" : "^";
|
850 |
+
regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
|
851 |
+
zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
|
852 |
+
_ref = this.results_data;
|
853 |
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
854 |
+
option = _ref[_i];
|
855 |
+
if (!option.disabled && !option.empty) {
|
856 |
+
if (option.group) {
|
857 |
+
$('#' + option.dom_id).css('display', 'none');
|
858 |
+
} else if (!(this.is_multiple && option.selected)) {
|
859 |
+
found = false;
|
860 |
+
result_id = option.dom_id;
|
861 |
+
result = $("#" + result_id);
|
862 |
+
if (regex.test(option.html)) {
|
863 |
+
found = true;
|
864 |
+
results += 1;
|
865 |
+
} else if (this.enable_split_word_search && (option.html.indexOf(" ") >= 0 || option.html.indexOf("[") === 0)) {
|
866 |
+
parts = option.html.replace(/\[|\]/g, "").split(" ");
|
867 |
+
if (parts.length) {
|
868 |
+
for (_j = 0, _len1 = parts.length; _j < _len1; _j++) {
|
869 |
+
part = parts[_j];
|
870 |
+
if (regex.test(part)) {
|
871 |
+
found = true;
|
872 |
+
results += 1;
|
873 |
+
}
|
874 |
+
}
|
875 |
+
}
|
876 |
+
}
|
877 |
+
if (found) {
|
878 |
+
if (searchText.length) {
|
879 |
+
startpos = option.html.search(zregex);
|
880 |
+
text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length);
|
881 |
+
text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
|
882 |
+
} else {
|
883 |
+
text = option.html;
|
884 |
+
}
|
885 |
+
result.html(text);
|
886 |
+
this.result_activate(result);
|
887 |
+
if (option.group_array_index != null) {
|
888 |
+
$("#" + this.results_data[option.group_array_index].dom_id).css('display', 'list-item');
|
889 |
+
}
|
890 |
+
} else {
|
891 |
+
if (this.result_highlight && result_id === this.result_highlight.attr('id')) {
|
892 |
+
this.result_clear_highlight();
|
893 |
+
}
|
894 |
+
this.result_deactivate(result);
|
895 |
+
}
|
896 |
+
}
|
897 |
+
}
|
898 |
+
}
|
899 |
+
if (results < 1 && searchText.length) {
|
900 |
+
return this.no_results(searchText);
|
901 |
+
} else {
|
902 |
+
return this.winnow_results_set_highlight();
|
903 |
+
}
|
904 |
+
};
|
905 |
+
|
906 |
+
Chosen.prototype.winnow_results_clear = function() {
|
907 |
+
var li, lis, _i, _len, _results;
|
908 |
+
this.search_field.val("");
|
909 |
+
lis = this.search_results.find("li");
|
910 |
+
_results = [];
|
911 |
+
for (_i = 0, _len = lis.length; _i < _len; _i++) {
|
912 |
+
li = lis[_i];
|
913 |
+
li = $(li);
|
914 |
+
if (li.hasClass("group-result")) {
|
915 |
+
_results.push(li.css('display', 'auto'));
|
916 |
+
} else if (!this.is_multiple || !li.hasClass("result-selected")) {
|
917 |
+
_results.push(this.result_activate(li));
|
918 |
+
} else {
|
919 |
+
_results.push(void 0);
|
920 |
+
}
|
921 |
+
}
|
922 |
+
return _results;
|
923 |
+
};
|
924 |
+
|
925 |
+
Chosen.prototype.winnow_results_set_highlight = function() {
|
926 |
+
var do_high, selected_results;
|
927 |
+
if (!this.result_highlight) {
|
928 |
+
selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
|
929 |
+
do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
|
930 |
+
if (do_high != null) {
|
931 |
+
return this.result_do_highlight(do_high);
|
932 |
+
}
|
933 |
+
}
|
934 |
+
};
|
935 |
+
|
936 |
+
Chosen.prototype.no_results = function(terms) {
|
937 |
+
var no_results_html;
|
938 |
+
no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
|
939 |
+
no_results_html.find("span").first().html(terms);
|
940 |
+
return this.search_results.append(no_results_html);
|
941 |
+
};
|
942 |
+
|
943 |
+
Chosen.prototype.no_results_clear = function() {
|
944 |
+
return this.search_results.find(".no-results").remove();
|
945 |
+
};
|
946 |
+
|
947 |
+
Chosen.prototype.keydown_arrow = function() {
|
948 |
+
var first_active, next_sib;
|
949 |
+
if (!this.result_highlight) {
|
950 |
+
first_active = this.search_results.find("li.active-result").first();
|
951 |
+
if (first_active) {
|
952 |
+
this.result_do_highlight($(first_active));
|
953 |
+
}
|
954 |
+
} else if (this.results_showing) {
|
955 |
+
next_sib = this.result_highlight.nextAll("li.active-result").first();
|
956 |
+
if (next_sib) {
|
957 |
+
this.result_do_highlight(next_sib);
|
958 |
+
}
|
959 |
+
}
|
960 |
+
if (!this.results_showing) {
|
961 |
+
return this.results_show();
|
962 |
+
}
|
963 |
+
};
|
964 |
+
|
965 |
+
Chosen.prototype.keyup_arrow = function() {
|
966 |
+
var prev_sibs;
|
967 |
+
if (!this.results_showing && !this.is_multiple) {
|
968 |
+
return this.results_show();
|
969 |
+
} else if (this.result_highlight) {
|
970 |
+
prev_sibs = this.result_highlight.prevAll("li.active-result");
|
971 |
+
if (prev_sibs.length) {
|
972 |
+
return this.result_do_highlight(prev_sibs.first());
|
973 |
+
} else {
|
974 |
+
if (this.choices > 0) {
|
975 |
+
this.results_hide();
|
976 |
+
}
|
977 |
+
return this.result_clear_highlight();
|
978 |
+
}
|
979 |
+
}
|
980 |
+
};
|
981 |
+
|
982 |
+
Chosen.prototype.keydown_backstroke = function() {
|
983 |
+
var next_available_destroy;
|
984 |
+
if (this.pending_backstroke) {
|
985 |
+
this.choice_destroy(this.pending_backstroke.find("a").first());
|
986 |
+
return this.clear_backstroke();
|
987 |
+
} else {
|
988 |
+
next_available_destroy = this.search_container.siblings("li.search-choice").last();
|
989 |
+
if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
|
990 |
+
this.pending_backstroke = next_available_destroy;
|
991 |
+
if (this.single_backstroke_delete) {
|
992 |
+
return this.keydown_backstroke();
|
993 |
+
} else {
|
994 |
+
return this.pending_backstroke.addClass("search-choice-focus");
|
995 |
+
}
|
996 |
+
}
|
997 |
+
}
|
998 |
+
};
|
999 |
+
|
1000 |
+
Chosen.prototype.clear_backstroke = function() {
|
1001 |
+
if (this.pending_backstroke) {
|
1002 |
+
this.pending_backstroke.removeClass("search-choice-focus");
|
1003 |
+
}
|
1004 |
+
return this.pending_backstroke = null;
|
1005 |
+
};
|
1006 |
+
|
1007 |
+
Chosen.prototype.keydown_checker = function(evt) {
|
1008 |
+
var stroke, _ref;
|
1009 |
+
stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
|
1010 |
+
this.search_field_scale();
|
1011 |
+
if (stroke !== 8 && this.pending_backstroke) {
|
1012 |
+
this.clear_backstroke();
|
1013 |
+
}
|
1014 |
+
switch (stroke) {
|
1015 |
+
case 8:
|
1016 |
+
this.backstroke_length = this.search_field.val().length;
|
1017 |
+
break;
|
1018 |
+
case 9:
|
1019 |
+
if (this.results_showing && !this.is_multiple) {
|
1020 |
+
this.result_select(evt);
|
1021 |
+
}
|
1022 |
+
this.mouse_on_container = false;
|
1023 |
+
break;
|
1024 |
+
case 13:
|
1025 |
+
evt.preventDefault();
|
1026 |
+
break;
|
1027 |
+
case 38:
|
1028 |
+
evt.preventDefault();
|
1029 |
+
this.keyup_arrow();
|
1030 |
+
break;
|
1031 |
+
case 40:
|
1032 |
+
this.keydown_arrow();
|
1033 |
+
break;
|
1034 |
+
}
|
1035 |
+
};
|
1036 |
+
|
1037 |
+
Chosen.prototype.search_field_scale = function() {
|
1038 |
+
var dd_top, div, h, style, style_block, styles, w, _i, _len;
|
1039 |
+
if (this.is_multiple) {
|
1040 |
+
h = 0;
|
1041 |
+
w = 0;
|
1042 |
+
style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
|
1043 |
+
styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
|
1044 |
+
for (_i = 0, _len = styles.length; _i < _len; _i++) {
|
1045 |
+
style = styles[_i];
|
1046 |
+
style_block += style + ":" + this.search_field.css(style) + ";";
|
1047 |
+
}
|
1048 |
+
div = $('<div />', {
|
1049 |
+
'style': style_block
|
1050 |
+
});
|
1051 |
+
div.text(this.search_field.val());
|
1052 |
+
$('body').append(div);
|
1053 |
+
w = div.width() + 25;
|
1054 |
+
div.remove();
|
1055 |
+
if (w > this.f_width - 10) {
|
1056 |
+
w = this.f_width - 10;
|
1057 |
+
}
|
1058 |
+
this.search_field.css({
|
1059 |
+
'width': w + 'px'
|
1060 |
+
});
|
1061 |
+
dd_top = this.container.height();
|
1062 |
+
return this.dropdown.css({
|
1063 |
+
"top": dd_top + "px"
|
1064 |
+
});
|
1065 |
+
}
|
1066 |
+
};
|
1067 |
+
|
1068 |
+
Chosen.prototype.generate_random_id = function() {
|
1069 |
+
var string;
|
1070 |
+
string = "sel" + this.generate_random_char() + this.generate_random_char() + this.generate_random_char();
|
1071 |
+
while ($("#" + string).length > 0) {
|
1072 |
+
string += this.generate_random_char();
|
1073 |
+
}
|
1074 |
+
return string;
|
1075 |
+
};
|
1076 |
+
|
1077 |
+
return Chosen;
|
1078 |
+
|
1079 |
+
})(AbstractChosen);
|
1080 |
+
|
1081 |
+
root.Chosen = Chosen;
|
1082 |
+
|
1083 |
+
get_side_border_padding = function(elmt) {
|
1084 |
+
var side_border_padding;
|
1085 |
+
return side_border_padding = elmt.outerWidth() - elmt.width();
|
1086 |
+
};
|
1087 |
+
|
1088 |
+
root.get_side_border_padding = get_side_border_padding;
|
1089 |
+
|
1090 |
+
}).call(this);
|
assets/js/chosen/chosen.jquery.min.js
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// Chosen, a Select Box Enhancer for jQuery and Protoype
|
2 |
+
// by Patrick Filler for Harvest, http://getharvest.com
|
3 |
+
//
|
4 |
+
// Version 0.9.12
|
5 |
+
// Full source at https://github.com/harvesthq/chosen
|
6 |
+
// Copyright (c) 2011 Harvest http://getharvest.com
|
7 |
+
|
8 |
+
// MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
|
9 |
+
// This file is generated by `cake build`, do not edit it by hand.
|
10 |
+
(function(){var e;e=function(){function e(){this.options_index=0,this.parsed=[]}return e.prototype.add_node=function(e){return e.nodeName.toUpperCase()==="OPTGROUP"?this.add_group(e):this.add_option(e)},e.prototype.add_group=function(e){var t,n,r,i,s,o;t=this.parsed.length,this.parsed.push({array_index:t,group:!0,label:e.label,children:0,disabled:e.disabled}),s=e.childNodes,o=[];for(r=0,i=s.length;r<i;r++)n=s[r],o.push(this.add_option(n,t,e.disabled));return o},e.prototype.add_option=function(e,t,n){if(e.nodeName.toUpperCase()==="OPTION")return e.text!==""?(t!=null&&(this.parsed[t].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:e.value,text:e.text,html:e.innerHTML,selected:e.selected,disabled:n===!0?n:e.disabled,group_array_index:t,classes:e.className,style:e.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1},e}(),e.select_to_array=function(t){var n,r,i,s,o;r=new e,o=t.childNodes;for(i=0,s=o.length;i<s;i++)n=o[i],r.add_node(n);return r.parsed},this.SelectParser=e}).call(this),function(){var e,t;t=this,e=function(){function e(e,t){this.form_field=e,this.options=t!=null?t:{},this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers(),this.finish_setup()}return e.prototype.set_default_values=function(){var e=this;return this.click_test_action=function(t){return e.test_active_click(t)},this.activate_action=function(t){return e.activate_field(t)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=this.options.allow_single_deselect!=null&&this.form_field.options[0]!=null&&this.form_field.options[0].text===""?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=this.options.enable_split_word_search!=null?this.options.enable_split_word_search:!0,this.search_contains=this.options.search_contains||!1,this.choices=0,this.single_backstroke_delete=this.options.single_backstroke_delete||!1,this.max_selected_options=this.options.max_selected_options||Infinity,this.inherit_select_classes=this.options.inherit_select_classes||!1},e.prototype.set_default_text=function(){return this.form_field.getAttribute("data-placeholder")?this.default_text=this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.default_text=this.options.placeholder_text_multiple||this.options.placeholder_text||"Select Some Options":this.default_text=this.options.placeholder_text_single||this.options.placeholder_text||"Select an Option",this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||"No results match"},e.prototype.mouse_enter=function(){return this.mouse_on_container=!0},e.prototype.mouse_leave=function(){return this.mouse_on_container=!1},e.prototype.input_focus=function(e){var t=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return t.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},e.prototype.input_blur=function(e){var t=this;if(!this.mouse_on_container)return this.active_field=!1,setTimeout(function(){return t.blur_test()},100)},e.prototype.result_add_option=function(e){var t,n;return e.disabled?"":(e.dom_id=this.container_id+"_o_"+e.array_index,t=e.selected&&this.is_multiple?[]:["active-result"],e.selected&&t.push("result-selected"),e.group_array_index!=null&&t.push("group-option"),e.classes!==""&&t.push(e.classes),n=e.style.cssText!==""?' style="'+e.style+'"':"",'<li id="'+e.dom_id+'" class="'+t.join(" ")+'"'+n+">"+e.html+"</li>")},e.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.result_single_selected=null,this.results_build()},e.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},e.prototype.results_search=function(e){return this.results_showing?this.winnow_results():this.results_show()},e.prototype.keyup_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale();switch(t){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:e.preventDefault();if(this.results_showing)return this.result_select(e);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},e.prototype.generate_field_id=function(){var e;return e=this.generate_random_id(),this.form_field.id=e,e},e.prototype.generate_random_char=function(){var e,t,n;return e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",n=Math.floor(Math.random()*e.length),t=e.substring(n,n+1)},e}(),t.AbstractChosen=e}.call(this),function(){var e,t,n,r,i={}.hasOwnProperty,s=function(e,t){function r(){this.constructor=e}for(var n in t)i.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e};r=this,e=jQuery,e.fn.extend({chosen:function(n){var r,i,s;return s=navigator.userAgent.toLowerCase(),i=/(msie) ([\w.]+)/.exec(s)||[],r={name:i[1]||"",version:i[2]||"0"},r.name==="msie"&&(r.version==="6.0"||r.version==="7.0"&&document.documentMode===7)?this:this.each(function(r){var i;i=e(this);if(!i.hasClass("chzn-done"))return i.data("chosen",new t(this,n))})}}),t=function(t){function i(){return i.__super__.constructor.apply(this,arguments)}return s(i,t),i.prototype.setup=function(){return this.form_field_jq=e(this.form_field),this.current_value=this.form_field_jq.val(),this.is_rtl=this.form_field_jq.hasClass("chzn-rtl")},i.prototype.finish_setup=function(){return this.form_field_jq.addClass("chzn-done")},i.prototype.set_up_html=function(){var t,r,i,s,o,u;return this.container_id=this.form_field.id.length?this.form_field.id.replace(/[^\w]/g,"_"):this.generate_field_id(),this.container_id+="_chzn",t=["chzn-container"],t.push("chzn-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&t.push(this.form_field.className),this.is_rtl&&t.push("chzn-rtl"),this.f_width=this.form_field_jq.outerWidth(),i={id:this.container_id,"class":t.join(" "),style:"width: "+this.f_width+"px;",title:this.form_field.title},r=e("<div />",i),this.is_multiple?r.html('<ul class="chzn-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chzn-drop" style="left:-9000px;"><ul class="chzn-results"></ul></div>'):r.html('<a href="javascript:void(0)" class="chzn-single chzn-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chzn-drop" style="left:-9000px;"><div class="chzn-search"><input type="text" autocomplete="off" /></div><ul class="chzn-results"></ul></div>'),this.form_field_jq.hide().after(r),this.container=e("#"+this.container_id),this.dropdown=this.container.find("div.chzn-drop").first(),s=this.container.height(),o=this.f_width-n(this.dropdown),this.dropdown.css({width:o+"px",top:s+"px"}),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chzn-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chzn-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chzn-search").first(),this.selected_item=this.container.find(".chzn-single").first(),u=o-n(this.search_container)-n(this.search_field),this.search_field.css({width:u+"px"})),this.results_build(),this.set_tab_index(),this.form_field_jq.trigger("liszt:ready",{chosen:this})},i.prototype.register_observers=function(){var e=this;return this.container.mousedown(function(t){e.container_mousedown(t)}),this.container.mouseup(function(t){e.container_mouseup(t)}),this.container.mouseenter(function(t){e.mouse_enter(t)}),this.container.mouseleave(function(t){e.mouse_leave(t)}),this.search_results.mouseup(function(t){e.search_results_mouseup(t)}),this.search_results.mouseover(function(t){e.search_results_mouseover(t)}),this.search_results.mouseout(function(t){e.search_results_mouseout(t)}),this.form_field_jq.bind("liszt:updated",function(t){e.results_update_field(t)}),this.form_field_jq.bind("liszt:activate",function(t){e.activate_field(t)}),this.form_field_jq.bind("liszt:open",function(t){e.container_mousedown(t)}),this.search_field.blur(function(t){e.input_blur(t)}),this.search_field.keyup(function(t){e.keyup_checker(t)}),this.search_field.keydown(function(t){e.keydown_checker(t)}),this.search_field.focus(function(t){e.input_focus(t)}),this.is_multiple?this.search_choices.click(function(t){e.choices_click(t)}):this.container.click(function(e){e.preventDefault()})},i.prototype.search_field_disabled=function(){this.is_disabled=this.form_field_jq[0].disabled;if(this.is_disabled)return this.container.addClass("chzn-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus",this.activate_action),this.close_field();this.container.removeClass("chzn-disabled"),this.search_field[0].disabled=!1;if(!this.is_multiple)return this.selected_item.bind("focus",this.activate_action)},i.prototype.container_mousedown=function(t){var n;if(!this.is_disabled)return n=t!=null?e(t.target).hasClass("search-choice-close"):!1,t&&t.type==="mousedown"&&!this.results_showing&&t.preventDefault(),!this.pending_destroy_click&&!n?(this.active_field?!this.is_multiple&&t&&(e(t.target)[0]===this.selected_item[0]||e(t.target).parents("a.chzn-single").length)&&(t.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),e(document).click(this.click_test_action),this.results_show()),this.activate_field()):this.pending_destroy_click=!1},i.prototype.container_mouseup=function(e){if(e.target.nodeName==="ABBR"&&!this.is_disabled)return this.results_reset(e)},i.prototype.blur_test=function(e){if(!this.active_field&&this.container.hasClass("chzn-container-active"))return this.close_field()},i.prototype.close_field=function(){return e(document).unbind("click",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chzn-container-active"),this.winnow_results_clear(),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},i.prototype.activate_field=function(){return this.container.addClass("chzn-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},i.prototype.test_active_click=function(t){return e(t.target).parents("#"+this.container_id).length?this.active_field=!0:this.close_field()},i.prototype.results_build=function(){var e,t,n,i,s;this.parsing=!0,this.results_data=r.SelectParser.select_to_array(this.form_field),this.is_multiple&&this.choices>0?(this.search_choices.find("li.search-choice").remove(),this.choices=0):this.is_multiple||(this.selected_item.addClass("chzn-default").find("span").text(this.default_text),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?this.container.addClass("chzn-container-single-nosearch"):this.container.removeClass("chzn-container-single-nosearch")),e="",s=this.results_data;for(n=0,i=s.length;n<i;n++)t=s[n],t.group?e+=this.result_add_group(t):t.empty||(e+=this.result_add_option(t),t.selected&&this.is_multiple?this.choice_build(t):t.selected&&!this.is_multiple&&(this.selected_item.removeClass("chzn-default").find("span").text(t.text),this.allow_single_deselect&&this.single_deselect_control_build()));return this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.search_results.html(e),this.parsing=!1},i.prototype.result_add_group=function(t){return t.disabled?"":(t.dom_id=this.container_id+"_g_"+t.array_index,'<li id="'+t.dom_id+'" class="group-result">'+e("<div />").text(t.label).html()+"</li>")},i.prototype.result_do_highlight=function(e){var t,n,r,i,s;if(e.length){this.result_clear_highlight(),this.result_highlight=e,this.result_highlight.addClass("highlighted"),r=parseInt(this.search_results.css("maxHeight"),10),s=this.search_results.scrollTop(),i=r+s,n=this.result_highlight.position().top+this.search_results.scrollTop(),t=n+this.result_highlight.outerHeight();if(t>=i)return this.search_results.scrollTop(t-r>0?t-r:0);if(n<s)return this.search_results.scrollTop(n)}},i.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},i.prototype.results_show=function(){var e;if(!this.is_multiple)this.selected_item.addClass("chzn-single-with-drop"),this.result_single_selected&&this.result_do_highlight(this.result_single_selected);else if(this.max_selected_options<=this.choices)return this.form_field_jq.trigger("liszt:maxselected",{chosen:this}),!1;return e=this.is_multiple?this.container.height():this.container.height()-1,this.form_field_jq.trigger("liszt:showing_dropdown",{chosen:this}),this.dropdown.css({top:e+"px",left:0}),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results()},i.prototype.results_hide=function(){return this.is_multiple||this.selected_item.removeClass("chzn-single-with-drop"),this.result_clear_highlight(),this.form_field_jq.trigger("liszt:hiding_dropdown",{chosen:this}),this.dropdown.css({left:"-9000px"}),this.results_showing=!1},i.prototype.set_tab_index=function(e){var t;if(this.form_field_jq.attr("tabindex"))return t=this.form_field_jq.attr("tabindex"),this.form_field_jq.attr("tabindex",-1),this.search_field.attr("tabindex",t)},i.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},i.prototype.search_results_mouseup=function(t){var n;n=e(t.target).hasClass("active-result")?e(t.target):e(t.target).parents(".active-result").first();if(n.length)return this.result_highlight=n,this.result_select(t),this.search_field.focus()},i.prototype.search_results_mouseover=function(t){var n;n=e(t.target).hasClass("active-result")?e(t.target):e(t.target).parents(".active-result").first();if(n)return this.result_do_highlight(n)},i.prototype.search_results_mouseout=function(t){if(e(t.target).hasClass("active-result"))return this.result_clear_highlight()},i.prototype.choices_click=function(t){t.preventDefault();if(this.active_field&&!e(t.target).hasClass("search-choice")&&!this.results_showing)return this.results_show()},i.prototype.choice_build=function(t){var n,r,i,s=this;return this.is_multiple&&this.max_selected_options<=this.choices?(this.form_field_jq.trigger("liszt:maxselected",{chosen:this}),!1):(n=this.container_id+"_c_"+t.array_index,this.choices+=1,t.disabled?r='<li class="search-choice search-choice-disabled" id="'+n+'"><span>'+t.html+"</span></li>":r='<li class="search-choice" id="'+n+'"><span>'+t.html+'</span><a href="javascript:void(0)" class="search-choice-close" rel="'+t.array_index+'"></a></li>',this.search_container.before(r),i=e("#"+n).find("a").first(),i.click(function(e){return s.choice_destroy_link_click(e)}))},i.prototype.choice_destroy_link_click=function(t){return t.preventDefault(),this.is_disabled?t.stopPropagation:(this.pending_destroy_click=!0,this.choice_destroy(e(t.target)))},i.prototype.choice_destroy=function(e){if(this.result_deselect(e.attr("rel")))return this.choices-=1,this.show_search_field_default(),this.is_multiple&&this.choices>0&&this.search_field.val().length<1&&this.results_hide(),e.parents("li").first().remove(),this.search_field_scale()},i.prototype.results_reset=function(){this.form_field.options[0].selected=!0,this.selected_item.find("span").text(this.default_text),this.is_multiple||this.selected_item.addClass("chzn-default"),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change");if(this.active_field)return this.results_hide()},i.prototype.results_reset_cleanup=function(){return this.current_value=this.form_field_jq.val(),this.selected_item.find("abbr").remove()},i.prototype.result_select=function(e){var t,n,r,i;if(this.result_highlight)return t=this.result_highlight,n=t.attr("id"),this.result_clear_highlight(),this.is_multiple?this.result_deactivate(t):(this.search_results.find(".result-selected").removeClass("result-selected"),this.result_single_selected=t,this.selected_item.removeClass("chzn-default")),t.addClass("result-selected"),i=n.substr(n.lastIndexOf("_")+1),r=this.results_data[i],r.selected=!0,this.form_field.options[r.options_index].selected=!0,this.is_multiple?this.choice_build(r):(this.selected_item.find("span").first().text(r.text),this.allow_single_deselect&&this.single_deselect_control_build()),(!e.metaKey&&!e.ctrlKey||!this.is_multiple)&&this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field_jq.val()!==this.current_value)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[r.options_index].value}),this.current_value=this.form_field_jq.val(),this.search_field_scale()},i.prototype.result_activate=function(e){return e.addClass("active-result")},i.prototype.result_deactivate=function(e){return e.removeClass("active-result")},i.prototype.result_deselect=function(t){var n,r;return r=this.results_data[t],this.form_field.options[r.options_index].disabled?!1:(r.selected=!1,this.form_field.options[r.options_index].selected=!1,n=e("#"+this.container_id+"_o_"+t),n.removeClass("result-selected").addClass("active-result").show(),this.result_clear_highlight(),this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[r.options_index].value}),this.search_field_scale(),!0)},i.prototype.single_deselect_control_build=function(){if(this.allow_single_deselect&&this.selected_item.find("abbr").length<1)return this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>')},i.prototype.winnow_results=function(){var t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y;this.no_results_clear(),f=0,l=this.search_field.val()===this.default_text?"":e("<div/>").text(e.trim(this.search_field.val())).html(),o=this.search_contains?"":"^",s=new RegExp(o+l.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),p=new RegExp(l.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"i"),y=this.results_data;for(d=0,m=y.length;d<m;d++){n=y[d];if(!n.disabled&&!n.empty)if(n.group)e("#"+n.dom_id).css("display","none");else if(!this.is_multiple||!n.selected){t=!1,a=n.dom_id,u=e("#"+a);if(s.test(n.html))t=!0,f+=1;else if(this.enable_split_word_search&&(n.html.indexOf(" ")>=0||n.html.indexOf("[")===0)){i=n.html.replace(/\[|\]/g,"").split(" ");if(i.length)for(v=0,g=i.length;v<g;v++)r=i[v],s.test(r)&&(t=!0,f+=1)}t?(l.length?(c=n.html.search(p),h=n.html.substr(0,c+l.length)+"</em>"+n.html.substr(c+l.length),h=h.substr(0,c)+"<em>"+h.substr(c)):h=n.html,u.html(h),this.result_activate(u),n.group_array_index!=null&&e("#"+this.results_data[n.group_array_index].dom_id).css("display","list-item")):(this.result_highlight&&a===this.result_highlight.attr("id")&&this.result_clear_highlight(),this.result_deactivate(u))}}return f<1&&l.length?this.no_results(l):this.winnow_results_set_highlight()},i.prototype.winnow_results_clear=function(){var t,n,r,i,s;this.search_field.val(""),n=this.search_results.find("li"),s=[];for(r=0,i=n.length;r<i;r++)t=n[r],t=e(t),t.hasClass("group-result")?s.push(t.css("display","auto")):!this.is_multiple||!t.hasClass("result-selected")?s.push(this.result_activate(t)):s.push(void 0);return s},i.prototype.winnow_results_set_highlight=function(){var e,t;if(!this.result_highlight){t=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),e=t.length?t.first():this.search_results.find(".active-result").first();if(e!=null)return this.result_do_highlight(e)}},i.prototype.no_results=function(t){var n;return n=e('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),n.find("span").first().html(t),this.search_results.append(n)},i.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},i.prototype.keydown_arrow=function(){var t,n;this.result_highlight?this.results_showing&&(n=this.result_highlight.nextAll("li.active-result").first(),n&&this.result_do_highlight(n)):(t=this.search_results.find("li.active-result").first(),t&&this.result_do_highlight(e(t)));if(!this.results_showing)return this.results_show()},i.prototype.keyup_arrow=function(){var e;if(!this.results_showing&&!this.is_multiple)return this.results_show();if(this.result_highlight)return e=this.result_highlight.prevAll("li.active-result"),e.length?this.result_do_highlight(e.first()):(this.choices>0&&this.results_hide(),this.result_clear_highlight())},i.prototype.keydown_backstroke=function(){var e;if(this.pending_backstroke)return this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke();e=this.search_container.siblings("li.search-choice").last();if(e.length&&!e.hasClass("search-choice-disabled"))return this.pending_backstroke=e,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")},i.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},i.prototype.keydown_checker=function(e){var t,n;t=(n=e.which)!=null?n:e.keyCode,this.search_field_scale(),t!==8&&this.pending_backstroke&&this.clear_backstroke();switch(t){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(e),this.mouse_on_container=!1;break;case 13:e.preventDefault();break;case 38:e.preventDefault(),this.keyup_arrow();break;case 40:this.keydown_arrow()}},i.prototype.search_field_scale=function(){var t,n,r,i,s,o,u,a,f;if(this.is_multiple){r=0,u=0,s="position:absolute; left: -1000px; top: -1000px; display:none;",o=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"];for(a=0,f=o.length;a<f;a++)i=o[a],s+=i+":"+this.search_field.css(i)+";";return n=e("<div />",{style:s}),n.text(this.search_field.val()),e("body").append(n),u=n.width()+25,n.remove(),u>this.f_width-10&&(u=this.f_width-10),this.search_field.css({width:u+"px"}),t=this.container.height(),this.dropdown.css({top:t+"px"})}},i.prototype.generate_random_id=function(){var t;t="sel"+this.generate_random_char()+this.generate_random_char()+this.generate_random_char();while(e("#"+t).length>0)t+=this.generate_random_char();return t},i}(AbstractChosen),r.Chosen=t,n=function(e){var t;return t=e.outerWidth()-e.width()},r.get_side_border_padding=n}.call(this);
|
assets/js/jqueryFileTree/connectors/jqueryFileTree.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//
|
3 |
+
// jQuery File Tree PHP Connector - modified for php4/wordpress compatibility
|
4 |
+
//
|
5 |
+
|
6 |
+
if(file_exists('../../../../../../wp-load.php')) {
|
7 |
+
require_once("../../../../../../wp-load.php");
|
8 |
+
} else if(file_exists('../../../../../../../wp-load.php')) {
|
9 |
+
require_once("../../../../../../../wp-load.php");
|
10 |
+
} else {
|
11 |
+
if(file_exists('../../../../../../wp-config.php')) {
|
12 |
+
require_once("../../../../../../wp-config.php");
|
13 |
+
} else if(file_exists('../../../../../../../wp-config.php')) {
|
14 |
+
require_once("../../../../../../../wp-config.php");
|
15 |
+
} else {
|
16 |
+
exit;
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
if (!function_exists('php4_scandir') && !function_exists('scandir')) {
|
21 |
+
function php4_scandir($dir,$listDirectories=true) {
|
22 |
+
$dirArray = array();
|
23 |
+
if ($handle = opendir($dir)) {
|
24 |
+
while (false !== ($file = readdir($handle))) {
|
25 |
+
if($listDirectories == false) { if(is_dir($file)) { continue; } }
|
26 |
+
array_push($dirArray,basename($file));
|
27 |
+
}
|
28 |
+
closedir($handle);
|
29 |
+
}
|
30 |
+
return $dirArray;
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
require_once(ABSPATH.'wp-admin/admin.php');
|
35 |
+
|
36 |
+
$_POST['dir'] = urldecode($_POST['dir']);
|
37 |
+
|
38 |
+
$root_dir = '';
|
39 |
+
|
40 |
+
if( file_exists($root_dir . $_POST['dir']) ) {
|
41 |
+
if (function_exists('scandir')) {
|
42 |
+
$files = scandir($root_dir . $_POST['dir']);
|
43 |
+
} else {
|
44 |
+
$files = php4_scandir($root_dir . $_POST['dir']);
|
45 |
+
}
|
46 |
+
natcasesort($files);
|
47 |
+
if( count($files) > 2 ) {
|
48 |
+
echo "<ul class=\"jqueryFileTree\" style=\"display: none;\">";
|
49 |
+
// All dirs
|
50 |
+
foreach( $files as $file ) {
|
51 |
+
if( file_exists($root_dir . $_POST['dir'] . $file) && $file != '.' && $file != '..' && is_dir($root_dir . $_POST['dir'] . $file) ) {
|
52 |
+
echo "<li class=\"directory collapsed\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file) . "/\">" . htmlentities($file) . "</a></li>";
|
53 |
+
}
|
54 |
+
}
|
55 |
+
// All files
|
56 |
+
foreach( $files as $file ) {
|
57 |
+
if( file_exists($root_dir . $_POST['dir'] . $file) && $file != '.' && $file != '..' && !is_dir($root_dir . $_POST['dir'] . $file) ) {
|
58 |
+
$ext = preg_replace('/^.*\./', '', $file);
|
59 |
+
echo "<li class=\"file ext_$ext\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file) . "\">" . htmlentities($file) . "</a></li>";
|
60 |
+
}
|
61 |
+
}
|
62 |
+
echo "</ul>";
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
?>
|
assets/js/jqueryFileTree/connectors/jqueryFileTreeDir.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//
|
3 |
+
// jQuery File Tree PHP Connector - modified for php4/wordpress compatibility
|
4 |
+
//
|
5 |
+
|
6 |
+
if(file_exists('../../../../../../wp-load.php')) {
|
7 |
+
require_once("../../../../../../wp-load.php");
|
8 |
+
} else if(file_exists('../../../../../../../wp-load.php')) {
|
9 |
+
require_once("../../../../../../../wp-load.php");
|
10 |
+
} else {
|
11 |
+
if(file_exists('../../../../../../wp-config.php')) {
|
12 |
+
require_once("../../../../../../wp-config.php");
|
13 |
+
} else if(file_exists('../../../../../../../wp-config.php')) {
|
14 |
+
require_once("../../../../../../../wp-config.php");
|
15 |
+
} else {
|
16 |
+
exit;
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
if (!function_exists('php4_scandir') && !function_exists('scandir')) {
|
21 |
+
function php4_scandir($dir,$listDirectories=true) {
|
22 |
+
$dirArray = array();
|
23 |
+
if ($handle = opendir($dir)) {
|
24 |
+
while (false !== ($file = readdir($handle))) {
|
25 |
+
if($listDirectories == false) { if(is_dir($file)) { continue; } }
|
26 |
+
array_push($dirArray,basename($file));
|
27 |
+
}
|
28 |
+
closedir($handle);
|
29 |
+
}
|
30 |
+
return $dirArray;
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
require_once(ABSPATH.'wp-admin/admin.php');
|
35 |
+
|
36 |
+
$_POST['dir'] = urldecode($_POST['dir']);
|
37 |
+
|
38 |
+
$root_dir = '';
|
39 |
+
|
40 |
+
if( file_exists($root_dir . $_POST['dir']) ) {
|
41 |
+
if (function_exists('scandir')) {
|
42 |
+
$files = scandir($root_dir . $_POST['dir']);
|
43 |
+
} else {
|
44 |
+
$files = php4_scandir($root_dir . $_POST['dir']);
|
45 |
+
}
|
46 |
+
natcasesort($files);
|
47 |
+
if( count($files) > 2 ) {
|
48 |
+
echo "<ul class=\"jqueryFileTree\" style=\"display: none;\">";
|
49 |
+
echo "<li class=\"file\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir']) . "\"><Select this directory></a></li>";
|
50 |
+
// All dirs
|
51 |
+
foreach( $files as $file ) {
|
52 |
+
if( file_exists($root_dir . $_POST['dir'] . $file) && $file != '.' && $file != '..' && is_dir($root_dir . $_POST['dir'] . $file) ) {
|
53 |
+
echo "<li class=\"directory collapsed\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file) . "/\">" . htmlentities($file) . "</a></li>";
|
54 |
+
}
|
55 |
+
}
|
56 |
+
echo "</ul>";
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
?>
|
assets/js/jqueryFileTree/images/application.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/code.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/css.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/db.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/directory.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/doc.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/file.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/film.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/flash.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/folder_open.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/html.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/java.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/linux.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/music.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/pdf.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/php.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/picture.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/ppt.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/psd.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/ruby.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/script.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/spinner.gif
ADDED
Binary file
|
assets/js/jqueryFileTree/images/txt.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/xls.png
ADDED
Binary file
|
assets/js/jqueryFileTree/images/zip.png
ADDED
Binary file
|
assets/js/jqueryFileTree/jqueryFileTree.css
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#file_browser, #file_browser2, #file_browser_thumbnail {
|
2 |
+
border: 1px solid #DFDFDF;
|
3 |
+
height: 250px;
|
4 |
+
overflow: auto;
|
5 |
+
padding: 4px 8px;
|
6 |
+
background: #fff;
|
7 |
+
margin: 4px 0;
|
8 |
+
width: 342px;
|
9 |
+
}
|
10 |
+
|
11 |
+
UL.jqueryFileTree {
|
12 |
+
font-family: Verdana, sans-serif;
|
13 |
+
font-size: 11px;
|
14 |
+
line-height: 18px;
|
15 |
+
padding: 0px;
|
16 |
+
margin: 0px;
|
17 |
+
}
|
18 |
+
|
19 |
+
UL.jqueryFileTree LI {
|
20 |
+
list-style: none;
|
21 |
+
padding: 2px 0px;
|
22 |
+
padding-left: 20px;
|
23 |
+
margin: 0px;
|
24 |
+
white-space: nowrap;
|
25 |
+
}
|
26 |
+
|
27 |
+
UL.jqueryFileTree A {
|
28 |
+
color: #333;
|
29 |
+
text-decoration: none;
|
30 |
+
display: block;
|
31 |
+
padding: 0px 2px;
|
32 |
+
}
|
33 |
+
|
34 |
+
UL.jqueryFileTree A:hover {
|
35 |
+
background: #BDF;
|
36 |
+
}
|
37 |
+
|
38 |
+
/* Core Styles */
|
39 |
+
.jqueryFileTree LI.directory { background: url(images/directory.png) left top no-repeat; }
|
40 |
+
.jqueryFileTree LI.expanded { background: url(images/folder_open.png) left top no-repeat; }
|
41 |
+
.jqueryFileTree LI.file { background: url(images/file.png) left top no-repeat; }
|
42 |
+
.jqueryFileTree LI.wait { background: url(images/spinner.gif) left top no-repeat; }
|
43 |
+
/* File Extensions*/
|
44 |
+
.jqueryFileTree LI.ext_3gp { background: url(images/film.png) left top no-repeat; }
|
45 |
+
.jqueryFileTree LI.ext_afp { background: url(images/code.png) left top no-repeat; }
|
46 |
+
.jqueryFileTree LI.ext_afpa { background: url(images/code.png) left top no-repeat; }
|
47 |
+
.jqueryFileTree LI.ext_asp { background: url(images/code.png) left top no-repeat; }
|
48 |
+
.jqueryFileTree LI.ext_aspx { background: url(images/code.png) left top no-repeat; }
|
49 |
+
.jqueryFileTree LI.ext_avi { background: url(images/film.png) left top no-repeat; }
|
50 |
+
.jqueryFileTree LI.ext_bat { background: url(images/application.png) left top no-repeat; }
|
51 |
+
.jqueryFileTree LI.ext_bmp { background: url(images/picture.png) left top no-repeat; }
|
52 |
+
.jqueryFileTree LI.ext_c { background: url(images/code.png) left top no-repeat; }
|
53 |
+
.jqueryFileTree LI.ext_cfm { background: url(images/code.png) left top no-repeat; }
|
54 |
+
.jqueryFileTree LI.ext_cgi { background: url(images/code.png) left top no-repeat; }
|
55 |
+
.jqueryFileTree LI.ext_com { background: url(images/application.png) left top no-repeat; }
|
56 |
+
.jqueryFileTree LI.ext_cpp { background: url(images/code.png) left top no-repeat; }
|
57 |
+
.jqueryFileTree LI.ext_css { background: url(images/css.png) left top no-repeat; }
|
58 |
+
.jqueryFileTree LI.ext_doc { background: url(images/doc.png) left top no-repeat; }
|
59 |
+
.jqueryFileTree LI.ext_exe { background: url(images/application.png) left top no-repeat; }
|
60 |
+
.jqueryFileTree LI.ext_gif { background: url(images/picture.png) left top no-repeat; }
|
61 |
+
.jqueryFileTree LI.ext_fla { background: url(images/flash.png) left top no-repeat; }
|
62 |
+
.jqueryFileTree LI.ext_h { background: url(images/code.png) left top no-repeat; }
|
63 |
+
.jqueryFileTree LI.ext_htm { background: url(images/html.png) left top no-repeat; }
|
64 |
+
.jqueryFileTree LI.ext_html { background: url(images/html.png) left top no-repeat; }
|
65 |
+
.jqueryFileTree LI.ext_jar { background: url(images/java.png) left top no-repeat; }
|
66 |
+
.jqueryFileTree LI.ext_jpg { background: url(images/picture.png) left top no-repeat; }
|
67 |
+
.jqueryFileTree LI.ext_jpeg { background: url(images/picture.png) left top no-repeat; }
|
68 |
+
.jqueryFileTree LI.ext_js { background: url(images/script.png) left top no-repeat; }
|
69 |
+
.jqueryFileTree LI.ext_lasso { background: url(images/code.png) left top no-repeat; }
|
70 |
+
.jqueryFileTree LI.ext_log { background: url(images/txt.png) left top no-repeat; }
|
71 |
+
.jqueryFileTree LI.ext_m4p { background: url(images/music.png) left top no-repeat; }
|
72 |
+
.jqueryFileTree LI.ext_mov { background: url(images/film.png) left top no-repeat; }
|
73 |
+
.jqueryFileTree LI.ext_mp3 { background: url(images/music.png) left top no-repeat; }
|
74 |
+
.jqueryFileTree LI.ext_mp4 { background: url(images/film.png) left top no-repeat; }
|
75 |
+
.jqueryFileTree LI.ext_mpg { background: url(images/film.png) left top no-repeat; }
|
76 |
+
.jqueryFileTree LI.ext_mpeg { background: url(images/film.png) left top no-repeat; }
|
77 |
+
.jqueryFileTree LI.ext_ogg { background: url(images/music.png) left top no-repeat; }
|
78 |
+
.jqueryFileTree LI.ext_pcx { background: url(images/picture.png) left top no-repeat; }
|
79 |
+
.jqueryFileTree LI.ext_pdf { background: url(images/pdf.png) left top no-repeat; }
|
80 |
+
.jqueryFileTree LI.ext_php { background: url(images/php.png) left top no-repeat; }
|
81 |
+
.jqueryFileTree LI.ext_png { background: url(images/picture.png) left top no-repeat; }
|
82 |
+
.jqueryFileTree LI.ext_ppt { background: url(images/ppt.png) left top no-repeat; }
|
83 |
+
.jqueryFileTree LI.ext_psd { background: url(images/psd.png) left top no-repeat; }
|
84 |
+
.jqueryFileTree LI.ext_pl { background: url(images/script.png) left top no-repeat; }
|
85 |
+
.jqueryFileTree LI.ext_py { background: url(images/script.png) left top no-repeat; }
|
86 |
+
.jqueryFileTree LI.ext_rb { background: url(images/ruby.png) left top no-repeat; }
|
87 |
+
.jqueryFileTree LI.ext_rbx { background: url(images/ruby.png) left top no-repeat; }
|
88 |
+
.jqueryFileTree LI.ext_rhtml { background: url(images/ruby.png) left top no-repeat; }
|
89 |
+
.jqueryFileTree LI.ext_rpm { background: url(images/linux.png) left top no-repeat; }
|
90 |
+
.jqueryFileTree LI.ext_ruby { background: url(images/ruby.png) left top no-repeat; }
|
91 |
+
.jqueryFileTree LI.ext_sql { background: url(images/db.png) left top no-repeat; }
|
92 |
+
.jqueryFileTree LI.ext_swf { background: url(images/flash.png) left top no-repeat; }
|
93 |
+
.jqueryFileTree LI.ext_tif { background: url(images/picture.png) left top no-repeat; }
|
94 |
+
.jqueryFileTree LI.ext_tiff { background: url(images/picture.png) left top no-repeat; }
|
95 |
+
.jqueryFileTree LI.ext_txt { background: url(images/txt.png) left top no-repeat; }
|
96 |
+
.jqueryFileTree LI.ext_vb { background: url(images/code.png) left top no-repeat; }
|
97 |
+
.jqueryFileTree LI.ext_wav { background: url(images/music.png) left top no-repeat; }
|
98 |
+
.jqueryFileTree LI.ext_wmv { background: url(images/film.png) left top no-repeat; }
|
99 |
+
.jqueryFileTree LI.ext_xls { background: url(images/xls.png) left top no-repeat; }
|
100 |
+
.jqueryFileTree LI.ext_xml { background: url(images/code.png) left top no-repeat; }
|
101 |
+
.jqueryFileTree LI.ext_zip { background: url(images/zip.png) left top no-repeat; }
|
assets/js/jqueryFileTree/jqueryFileTree.js
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// jQuery File Tree Plugin
|
2 |
+
//
|
3 |
+
// Version 1.01
|
4 |
+
//
|
5 |
+
// Cory S.N. LaViska
|
6 |
+
// A Beautiful Site (http://abeautifulsite.net/)
|
7 |
+
// 24 March 2008
|
8 |
+
//
|
9 |
+
// Visit http://abeautifulsite.net/notebook.php?article=58 for more information
|
10 |
+
//
|
11 |
+
// Usage: $('.fileTreeDemo').fileTree( options, callback )
|
12 |
+
//
|
13 |
+
// Options: root - root folder to display; default = /
|
14 |
+
// script - location of the serverside AJAX file to use; default = jqueryFileTree.php
|
15 |
+
// folderEvent - event to trigger expand/collapse; default = click
|
16 |
+
// expandSpeed - default = 500 (ms); use -1 for no animation
|
17 |
+
// collapseSpeed - default = 500 (ms); use -1 for no animation
|
18 |
+
// expandEasing - easing function to use on expand (optional)
|
19 |
+
// collapseEasing - easing function to use on collapse (optional)
|
20 |
+
// multiFolder - whether or not to limit the browser to one subfolder at a time
|
21 |
+
// loadMessage - Message to display while initial tree loads (can be HTML)
|
22 |
+
//
|
23 |
+
// History:
|
24 |
+
//
|
25 |
+
// 1.01 - updated to work with foreign characters in directory/file names (12 April 2008)
|
26 |
+
// 1.00 - released (24 March 2008)
|
27 |
+
//
|
28 |
+
// TERMS OF USE
|
29 |
+
//
|
30 |
+
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
|
31 |
+
// is copyright 2008 A Beautiful Site, LLC.
|
32 |
+
//
|
33 |
+
if(jQuery) (function($){
|
34 |
+
|
35 |
+
$.extend($.fn, {
|
36 |
+
fileTree: function(o, h) {
|
37 |
+
// Defaults
|
38 |
+
if( !o ) var o = {};
|
39 |
+
if( o.root == undefined ) o.root = '/';
|
40 |
+
if( o.script == undefined ) o.script = 'jqueryFileTree.php';
|
41 |
+
if( o.folderEvent == undefined ) o.folderEvent = 'click';
|
42 |
+
if( o.expandSpeed == undefined ) o.expandSpeed= 500;
|
43 |
+
if( o.collapseSpeed == undefined ) o.collapseSpeed= 500;
|
44 |
+
if( o.expandEasing == undefined ) o.expandEasing = null;
|
45 |
+
if( o.collapseEasing == undefined ) o.collapseEasing = null;
|
46 |
+
if( o.multiFolder == undefined ) o.multiFolder = true;
|
47 |
+
if( o.loadMessage == undefined ) o.loadMessage = 'Loading...';
|
48 |
+
|
49 |
+
$(this).each( function() {
|
50 |
+
|
51 |
+
function showTree(c, t) {
|
52 |
+
$(c).addClass('wait');
|
53 |
+
$(".jqueryFileTree.start").remove();
|
54 |
+
$.post(o.script, { dir: t }, function(data) {
|
55 |
+
$(c).find('.start').html('');
|
56 |
+
$(c).removeClass('wait').append(data);
|
57 |
+
if( o.root == t ) $(c).find('UL:hidden').show(); else $(c).find('UL:hidden').slideDown({ duration: o.expandSpeed, easing: o.expandEasing });
|
58 |
+
bindTree(c);
|
59 |
+
});
|
60 |
+
}
|
61 |
+
|
62 |
+
function bindTree(t) {
|
63 |
+
$(t).find('LI A').bind(o.folderEvent, function() {
|
64 |
+
if( $(this).parent().hasClass('directory') ) {
|
65 |
+
if( $(this).parent().hasClass('collapsed') ) {
|
66 |
+
// Expand
|
67 |
+
if( !o.multiFolder ) {
|
68 |
+
$(this).parent().parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
|
69 |
+
$(this).parent().parent().find('LI.directory').removeClass('expanded').addClass('collapsed');
|
70 |
+
}
|
71 |
+
$(this).parent().find('UL').remove(); // cleanup
|
72 |
+
showTree( $(this).parent(), escape($(this).attr('rel').match( /.*\// )) );
|
73 |
+
$(this).parent().removeClass('collapsed').addClass('expanded');
|
74 |
+
} else {
|
75 |
+
// Collapse
|
76 |
+
$(this).parent().find('UL').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
|
77 |
+
$(this).parent().removeClass('expanded').addClass('collapsed');
|
78 |
+
}
|
79 |
+
} else {
|
80 |
+
h($(this).attr('rel'));
|
81 |
+
}
|
82 |
+
return false;
|
83 |
+
});
|
84 |
+
// Prevent A from triggering the # on non-click events
|
85 |
+
if( o.folderEvent.toLowerCase != 'click' ) $(t).find('LI A').bind('click', function() { return false; });
|
86 |
+
}
|
87 |
+
// Loading message
|
88 |
+
$(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>');
|
89 |
+
// Get the initial file list
|
90 |
+
showTree( $(this), escape(o.root) );
|
91 |
+
});
|
92 |
+
}
|
93 |
+
});
|
94 |
+
|
95 |
+
})(jQuery);
|
download-monitor.php
ADDED
@@ -0,0 +1,535 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Download Monitor
|
4 |
+
Plugin URI: http://mikejolley.com/projects/download-monitor/
|
5 |
+
Description: A full solution for managing downloadable files, monitoring downloads and outputting download links and file information on your WordPress powered site.
|
6 |
+
Version: 1.0.0
|
7 |
+
Author: Mike Jolley
|
8 |
+
Author URI: http://mikejolley.com
|
9 |
+
Requires at least: 3.5
|
10 |
+
Tested up to: 3.5
|
11 |
+
|
12 |
+
Copyright: � 2013 Mike Jolley.
|
13 |
+
License: GNU General Public License v3.0
|
14 |
+
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
15 |
+
|
16 |
+
Filetype icons from the Fugue Icon Pack by Yusuke Kamiyamane.
|
17 |
+
*/
|
18 |
+
|
19 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
20 |
+
|
21 |
+
/**
|
22 |
+
* WP_Download_Monitor class.
|
23 |
+
*
|
24 |
+
* Main Class which inits the CPT and plugin
|
25 |
+
*/
|
26 |
+
class WP_DLM {
|
27 |
+
|
28 |
+
private $plugin_url;
|
29 |
+
private $plugin_path;
|
30 |
+
private $_inline_js;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* __construct function.
|
34 |
+
*
|
35 |
+
* @access public
|
36 |
+
* @return void
|
37 |
+
*/
|
38 |
+
public function __construct() {
|
39 |
+
global $wpdb;
|
40 |
+
|
41 |
+
// Define constants
|
42 |
+
define( 'DLM_VERSION', '1.0.0' );
|
43 |
+
|
44 |
+
// Table for logs
|
45 |
+
$wpdb->download_log = $wpdb->prefix . 'download_log';
|
46 |
+
|
47 |
+
// Include required files
|
48 |
+
if ( is_admin() )
|
49 |
+
include_once( 'includes/admin/class-dlm-admin.php' );
|
50 |
+
|
51 |
+
if ( defined('DOING_AJAX') )
|
52 |
+
include_once( 'includes/class-dlm-ajax-handler.php' );
|
53 |
+
|
54 |
+
if ( get_option( 'dlm_enable_logging' ) == 1 )
|
55 |
+
include_once( 'includes/class-dlm-logging.php' );
|
56 |
+
|
57 |
+
include_once( 'includes/class-dlm-download.php' );
|
58 |
+
include_once( 'includes/class-dlm-download-version.php' );
|
59 |
+
include_once( 'includes/class-dlm-download-handler.php' );
|
60 |
+
include_once( 'includes/class-dlm-shortcodes.php' );
|
61 |
+
|
62 |
+
// Activation
|
63 |
+
register_activation_hook( __FILE__, array( $this, 'init_user_roles' ), 10 );
|
64 |
+
register_activation_hook( __FILE__, array( $this, 'init_taxonomy' ), 10 );
|
65 |
+
register_activation_hook( __FILE__, array( $this, 'install_tables' ), 10 );
|
66 |
+
register_activation_hook( __FILE__, array( $this, 'directory_protection' ), 10 );
|
67 |
+
register_activation_hook( __FILE__, array( $GLOBALS['DLM_Download_Handler'], 'add_endpoint' ), 10 );
|
68 |
+
register_activation_hook( __FILE__, 'flush_rewrite_rules', 11 );
|
69 |
+
|
70 |
+
// Actions
|
71 |
+
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_links' ) );
|
72 |
+
add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
|
73 |
+
add_action( 'init', array( $this, 'register_globals' ) );
|
74 |
+
add_action( 'init', array( $this, 'init_taxonomy' ) );
|
75 |
+
add_action( 'after_setup_theme', array( $this, 'compatibility' ) );
|
76 |
+
add_action( 'the_post', array( $this, 'setup_download_data' ) );
|
77 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) );
|
78 |
+
add_action( 'wp_footer', array( $this, 'output_inline_js' ), 25 );
|
79 |
+
add_action( 'admin_footer', array( $this, 'output_inline_js' ), 25 );
|
80 |
+
add_action( 'widgets_init', array( $this, 'register_widgets' ) );
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Add links to admin plugins page.
|
85 |
+
* @param array $links
|
86 |
+
* @return array
|
87 |
+
*/
|
88 |
+
public function plugin_links( $links ) {
|
89 |
+
$plugin_links = array(
|
90 |
+
'<a href="' . admin_url( 'edit.php?post_type=dlm_download&page=download-monitor-settings' ) . '">' . __( 'Settings', 'download_monitor' ) . '</a>',
|
91 |
+
'<a href="http://mikejolley.com/projects/download-monitor/add-ons/">' . __( 'Add-ons', 'download_monitor' ) . '</a>',
|
92 |
+
'<a href="https://github.com/mikejolley/download-monitor/wiki">' . __( 'Docs', 'download_monitor' ) . '</a>',
|
93 |
+
);
|
94 |
+
return array_merge( $plugin_links, $links );
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* frontend_scripts function.
|
99 |
+
*
|
100 |
+
* @access public
|
101 |
+
* @return void
|
102 |
+
*/
|
103 |
+
public function frontend_scripts() {
|
104 |
+
wp_enqueue_style( 'dlm-frontend', $this->plugin_url() . '/assets/css/frontend.css' );
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Localisation
|
109 |
+
*
|
110 |
+
* @access private
|
111 |
+
* @return void
|
112 |
+
*/
|
113 |
+
public function load_plugin_textdomain() {
|
114 |
+
load_textdomain( 'download_monitor', WP_LANG_DIR . '/download-monitor/download_monitor-' . get_locale() . '.mo' );
|
115 |
+
load_plugin_textdomain( 'download_monitor', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Register environment globals
|
120 |
+
*
|
121 |
+
* @access private
|
122 |
+
* @return void
|
123 |
+
*/
|
124 |
+
public function register_globals() {
|
125 |
+
$GLOBALS['dlm_download'] = null;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* When the_post is called, get product data too
|
130 |
+
*
|
131 |
+
* @access public
|
132 |
+
* @param mixed $post
|
133 |
+
* @return void
|
134 |
+
*/
|
135 |
+
public function setup_download_data( $post ) {
|
136 |
+
if ( is_int( $post ) )
|
137 |
+
$post = get_post( $post );
|
138 |
+
|
139 |
+
if ( $post->post_type !== 'dlm_download' )
|
140 |
+
return;
|
141 |
+
|
142 |
+
$GLOBALS['dlm_download'] = new DLM_Download( $post->ID );
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Add Theme Compatibility
|
147 |
+
*
|
148 |
+
* @access public
|
149 |
+
* @return void
|
150 |
+
*/
|
151 |
+
public function compatibility() {
|
152 |
+
// Post thumbnail support
|
153 |
+
if ( ! current_theme_supports( 'post-thumbnails' ) ) {
|
154 |
+
add_theme_support( 'post-thumbnails' );
|
155 |
+
remove_post_type_support( 'post', 'thumbnail' );
|
156 |
+
remove_post_type_support( 'page', 'thumbnail' );
|
157 |
+
} else {
|
158 |
+
add_post_type_support( 'download', 'thumbnail' );
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* install_tables function.
|
164 |
+
*
|
165 |
+
* @access public
|
166 |
+
* @return void
|
167 |
+
*/
|
168 |
+
public function install_tables() {
|
169 |
+
global $wpdb;
|
170 |
+
|
171 |
+
$wpdb->hide_errors();
|
172 |
+
|
173 |
+
$collate = '';
|
174 |
+
|
175 |
+
if ( $wpdb->has_cap( 'collation' ) ) {
|
176 |
+
if( ! empty( $wpdb->charset ) )
|
177 |
+
$collate .= "DEFAULT CHARACTER SET $wpdb->charset";
|
178 |
+
if( ! empty( $wpdb->collate ) )
|
179 |
+
$collate .= " COLLATE $wpdb->collate";
|
180 |
+
}
|
181 |
+
|
182 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
183 |
+
|
184 |
+
// WooCommerce Tables
|
185 |
+
$dlm_tables = "
|
186 |
+
CREATE TABLE {$wpdb->download_log} (
|
187 |
+
ID bigint(20) NOT NULL auto_increment,
|
188 |
+
type varchar(200) NOT NULL default 'download',
|
189 |
+
user_id bigint(20) NOT NULL,
|
190 |
+
user_ip varchar(200) NOT NULL,
|
191 |
+
user_agent varchar(200) NOT NULL,
|
192 |
+
download_id bigint(20) NOT NULL,
|
193 |
+
version_id bigint(20) NOT NULL,
|
194 |
+
version varchar(200) NOT NULL,
|
195 |
+
download_date datetime NOT NULL default '0000-00-00 00:00:00',
|
196 |
+
download_status varchar(200) NULL,
|
197 |
+
download_status_message varchar(200) NULL,
|
198 |
+
PRIMARY KEY (ID),
|
199 |
+
KEY attribute_name (download_id)
|
200 |
+
) $collate;
|
201 |
+
";
|
202 |
+
dbDelta( $dlm_tables );
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Init user roles
|
207 |
+
*
|
208 |
+
* @access public
|
209 |
+
* @return void
|
210 |
+
*/
|
211 |
+
public function init_user_roles() {
|
212 |
+
global $wp_roles;
|
213 |
+
|
214 |
+
if ( class_exists('WP_Roles') && ! isset( $wp_roles ) )
|
215 |
+
$wp_roles = new WP_Roles();
|
216 |
+
|
217 |
+
if ( is_object( $wp_roles ) ) {
|
218 |
+
$wp_roles->add_cap( 'administrator', 'manage_downloads' );
|
219 |
+
}
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Init taxonomies
|
224 |
+
*
|
225 |
+
* @access public
|
226 |
+
* @return void
|
227 |
+
*/
|
228 |
+
public function init_taxonomy() {
|
229 |
+
|
230 |
+
if ( post_type_exists( "dlm_download" ) )
|
231 |
+
return;
|
232 |
+
/**
|
233 |
+
* Taxonomies
|
234 |
+
*/
|
235 |
+
register_taxonomy( 'dlm_download_category',
|
236 |
+
array( 'dlm_download' ),
|
237 |
+
array(
|
238 |
+
'hierarchical' => true,
|
239 |
+
'update_count_callback' => '_update_post_term_count',
|
240 |
+
'label' => __( 'Categories', 'download_monitor'),
|
241 |
+
'labels' => array(
|
242 |
+
'name' => __( 'Categories', 'download_monitor'),
|
243 |
+
'singular_name' => __( 'Download Category', 'download_monitor'),
|
244 |
+
'search_items' => __( 'Search Download Categories', 'download_monitor'),
|
245 |
+
'all_items' => __( 'All Download Categories', 'download_monitor'),
|
246 |
+
'parent_item' => __( 'Parent Download Category', 'download_monitor'),
|
247 |
+
'parent_item_colon' => __( 'Parent Download Category:', 'download_monitor'),
|
248 |
+
'edit_item' => __( 'Edit Download Category', 'download_monitor'),
|
249 |
+
'update_item' => __( 'Update Download Category', 'download_monitor'),
|
250 |
+
'add_new_item' => __( 'Add New Download Category', 'download_monitor'),
|
251 |
+
'new_item_name' => __( 'New Download Category Name', 'download_monitor')
|
252 |
+
),
|
253 |
+
'show_ui' => true,
|
254 |
+
'query_var' => true,
|
255 |
+
'capabilities' => array(
|
256 |
+
'manage_terms' => 'manage_downloads',
|
257 |
+
'edit_terms' => 'manage_downloads',
|
258 |
+
'delete_terms' => 'manage_downloads',
|
259 |
+
'assign_terms' => 'manage_downloads',
|
260 |
+
),
|
261 |
+
'rewrite' => false,
|
262 |
+
)
|
263 |
+
);
|
264 |
+
|
265 |
+
register_taxonomy( 'dlm_download_tag',
|
266 |
+
array( 'dlm_download' ),
|
267 |
+
array(
|
268 |
+
'hierarchical' => false,
|
269 |
+
'label' => __( 'Tags', 'download_monitor'),
|
270 |
+
'labels' => array(
|
271 |
+
'name' => __( 'Tags', 'download_monitor'),
|
272 |
+
'singular_name' => __( 'Download Tag', 'download_monitor'),
|
273 |
+
'search_items' => __( 'Search Download Tags', 'download_monitor'),
|
274 |
+
'all_items' => __( 'All Download Tags', 'download_monitor'),
|
275 |
+
'parent_item' => __( 'Parent Download Tag', 'download_monitor'),
|
276 |
+
'parent_item_colon' => __( 'Parent Download Tag:', 'download_monitor'),
|
277 |
+
'edit_item' => __( 'Edit Download Tag', 'download_monitor'),
|
278 |
+
'update_item' => __( 'Update Download Tag', 'download_monitor'),
|
279 |
+
'add_new_item' => __( 'Add New Download Tag', 'download_monitor'),
|
280 |
+
'new_item_name' => __( 'New Download Tag Name', 'download_monitor')
|
281 |
+
),
|
282 |
+
'show_ui' => true,
|
283 |
+
'query_var' => true,
|
284 |
+
'capabilities' => array(
|
285 |
+
'manage_terms' => 'manage_downloads',
|
286 |
+
'edit_terms' => 'manage_downloads',
|
287 |
+
'delete_terms' => 'manage_downloads',
|
288 |
+
'assign_terms' => 'manage_downloads',
|
289 |
+
),
|
290 |
+
'rewrite' => false,
|
291 |
+
)
|
292 |
+
);
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Post Types
|
296 |
+
*/
|
297 |
+
register_post_type( "dlm_download",
|
298 |
+
apply_filters( 'dlm_cpt_dlm_download_args', array(
|
299 |
+
'labels' => array(
|
300 |
+
'name' => __( 'Downloads', 'download_monitor' ),
|
301 |
+
'singular_name' => __( 'Download', 'download_monitor' ),
|
302 |
+
'add_new' => __( 'Add New', 'download_monitor' ),
|
303 |
+
'add_new_item' => __( 'Add Download', 'download_monitor' ),
|
304 |
+
'edit' => __( 'Edit', 'download_monitor' ),
|
305 |
+
'edit_item' => __( 'Edit Download', 'download_monitor' ),
|
306 |
+
'new_item' => __( 'New Download', 'download_monitor' ),
|
307 |
+
'view' => __( 'View Download', 'download_monitor' ),
|
308 |
+
'view_item' => __( 'View Download', 'download_monitor' ),
|
309 |
+
'search_items' => __( 'Search Downloads', 'download_monitor' ),
|
310 |
+
'not_found' => __( 'No Downloads found', 'download_monitor' ),
|
311 |
+
'not_found_in_trash' => __( 'No Downloads found in trash', 'download_monitor' ),
|
312 |
+
'parent' => __( 'Parent Download', 'download_monitor' )
|
313 |
+
),
|
314 |
+
'description' => __( 'This is where you can create and manage downloads for your site.', 'download_monitor' ),
|
315 |
+
'public' => false,
|
316 |
+
'show_ui' => true,
|
317 |
+
'capability_type' => 'post',
|
318 |
+
'capabilities' => array(
|
319 |
+
'publish_posts' => 'manage_downloads',
|
320 |
+
'edit_posts' => 'manage_downloads',
|
321 |
+
'edit_others_posts' => 'manage_downloads',
|
322 |
+
'delete_posts' => 'manage_downloads',
|
323 |
+
'delete_others_posts' => 'manage_downloads',
|
324 |
+
'read_private_posts' => 'manage_downloads',
|
325 |
+
'edit_post' => 'manage_downloads',
|
326 |
+
'delete_post' => 'manage_downloads',
|
327 |
+
'read_post' => 'manage_downloads'
|
328 |
+
),
|
329 |
+
'publicly_queryable' => false,
|
330 |
+
'exclude_from_search' => false,
|
331 |
+
'hierarchical' => false,
|
332 |
+
'rewrite' => false,
|
333 |
+
'query_var' => true,
|
334 |
+
'supports' => apply_filters( 'dlm_cpt_dlm_download_supports', array( 'title', 'editor', 'excerpt', 'thumbnail', 'custom-fields' ) ),
|
335 |
+
'has_archive' => false,
|
336 |
+
'show_in_nav_menus' => false
|
337 |
+
) )
|
338 |
+
);
|
339 |
+
|
340 |
+
register_post_type( "dlm_download_version",
|
341 |
+
apply_filters( 'dlm_cpt_dlm_download_version_args', array(
|
342 |
+
'public' => false,
|
343 |
+
'show_ui' => false,
|
344 |
+
'publicly_queryable' => false,
|
345 |
+
'exclude_from_search' => true,
|
346 |
+
'hierarchical' => false,
|
347 |
+
'rewrite' => false,
|
348 |
+
'query_var' => false,
|
349 |
+
'show_in_nav_menus' => false
|
350 |
+
) )
|
351 |
+
);
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* register_widgets function.
|
356 |
+
*
|
357 |
+
* @access public
|
358 |
+
* @return void
|
359 |
+
*/
|
360 |
+
function register_widgets() {
|
361 |
+
include_once( 'includes/widgets/class-dlm-widget-downloads.php' );
|
362 |
+
|
363 |
+
register_widget( 'DLM_Widget_Downloads' );
|
364 |
+
}
|
365 |
+
|
366 |
+
/** Helper functions *****************************************************/
|
367 |
+
|
368 |
+
/**
|
369 |
+
* get_template_part function.
|
370 |
+
*
|
371 |
+
* @access public
|
372 |
+
* @param mixed $slug
|
373 |
+
* @param string $name (default: '')
|
374 |
+
* @return void
|
375 |
+
*/
|
376 |
+
public function get_template_part( $slug, $name = '', $custom_dir = '' ) {
|
377 |
+
$template = '';
|
378 |
+
|
379 |
+
// Look in yourtheme/slug-name.php and yourtheme/download-monitor/slug-name.php
|
380 |
+
if ( $name )
|
381 |
+
$template = locate_template( array ( "{$slug}-{$name}.php", "download-monitor/{$slug}-{$name}.php" ) );
|
382 |
+
|
383 |
+
// Get default slug-name.php
|
384 |
+
if ( ! $template && $name && file_exists( $this->plugin_path() . "/templates/{$slug}-{$name}.php" ) )
|
385 |
+
$template = $this->plugin_path() . "/templates/{$slug}-{$name}.php";
|
386 |
+
|
387 |
+
// If a custom path was defined, check that next
|
388 |
+
if ( ! $template && $custom_dir && file_exists( trailingslashit( $custom_dir ) . "{$slug}-{$name}.php" ) )
|
389 |
+
$template = trailingslashit( $custom_dir ) . "{$slug}-{$name}.php";
|
390 |
+
|
391 |
+
// If template file doesn't exist, look in yourtheme/slug.php and yourtheme/download-monitor/slug.php
|
392 |
+
if ( ! $template )
|
393 |
+
$template = locate_template( array( "{$slug}.php", "download-monitor/{$slug}.php" ) );
|
394 |
+
|
395 |
+
// If a custom path was defined, check that next
|
396 |
+
if ( ! $template && $custom_dir && file_exists( trailingslashit( $custom_dir ) . "{$slug}-{$name}.php" ) )
|
397 |
+
$template = trailingslashit( $custom_dir ) . "{$slug}.php";
|
398 |
+
|
399 |
+
// Get default slug-name.php
|
400 |
+
if ( ! $template && file_exists( $this->plugin_path() . "/templates/{$slug}.php" ) )
|
401 |
+
$template = $this->plugin_path() . "/templates/{$slug}.php";
|
402 |
+
|
403 |
+
if ( $template )
|
404 |
+
load_template( $template, false );
|
405 |
+
}
|
406 |
+
|
407 |
+
/**
|
408 |
+
* Get the plugin url
|
409 |
+
*
|
410 |
+
* @access public
|
411 |
+
* @return string
|
412 |
+
*/
|
413 |
+
public function plugin_url() {
|
414 |
+
if ( $this->plugin_url )
|
415 |
+
return $this->plugin_url;
|
416 |
+
|
417 |
+
return $this->plugin_url = plugins_url( basename( plugin_dir_path(__FILE__) ), basename( __FILE__ ) );
|
418 |
+
}
|
419 |
+
|
420 |
+
/**
|
421 |
+
* Get the plugin path
|
422 |
+
*
|
423 |
+
* @access public
|
424 |
+
* @return string
|
425 |
+
*/
|
426 |
+
public function plugin_path() {
|
427 |
+
if ( $this->plugin_path )
|
428 |
+
return $this->plugin_path;
|
429 |
+
|
430 |
+
return $this->plugin_path = plugin_dir_path( __FILE__ );
|
431 |
+
}
|
432 |
+
|
433 |
+
/**
|
434 |
+
* Enqueue JS to be added to the footer.
|
435 |
+
*
|
436 |
+
* @access public
|
437 |
+
* @param mixed $code
|
438 |
+
* @return void
|
439 |
+
*/
|
440 |
+
public function add_inline_js( $code ) {
|
441 |
+
$this->_inline_js .= "\n" . $code . "\n";
|
442 |
+
}
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Output enqueued JS
|
446 |
+
*
|
447 |
+
* @access public
|
448 |
+
* @return void
|
449 |
+
*/
|
450 |
+
public function output_inline_js() {
|
451 |
+
if ( $this->_inline_js ) {
|
452 |
+
echo "<!-- Download Monitor JavaScript-->\n<script type=\"text/javascript\">\njQuery(document).ready(function($) {";
|
453 |
+
echo $this->_inline_js;
|
454 |
+
echo "});\n</script>\n";
|
455 |
+
$this->_inline_js = '';
|
456 |
+
}
|
457 |
+
}
|
458 |
+
|
459 |
+
/**
|
460 |
+
* Returns a listing of all files in the specified folder and all subdirectories up to 100 levels deep.
|
461 |
+
* The depth of the recursiveness can be controlled by the $levels param.
|
462 |
+
*
|
463 |
+
* @access public
|
464 |
+
* @param string $folder (default: '')
|
465 |
+
* @return void
|
466 |
+
*/
|
467 |
+
function list_files( $folder = '' ) {
|
468 |
+
if ( empty($folder) )
|
469 |
+
return false;
|
470 |
+
|
471 |
+
$files = array();
|
472 |
+
if ( $dir = @opendir( $folder ) ) {
|
473 |
+
while (($file = readdir( $dir ) ) !== false ) {
|
474 |
+
if ( in_array($file, array('.', '..') ) )
|
475 |
+
continue;
|
476 |
+
if ( is_dir( $folder . '/' . $file ) ) {
|
477 |
+
|
478 |
+
$files[] = array(
|
479 |
+
'type' => 'folder',
|
480 |
+
'path' => $folder . '/' . $file
|
481 |
+
);
|
482 |
+
|
483 |
+
} else {
|
484 |
+
|
485 |
+
$files[] = array(
|
486 |
+
'type' => 'file',
|
487 |
+
'path' => $folder . '/' . $file
|
488 |
+
);
|
489 |
+
|
490 |
+
}
|
491 |
+
}
|
492 |
+
}
|
493 |
+
@closedir( $dir );
|
494 |
+
return $files;
|
495 |
+
}
|
496 |
+
|
497 |
+
/**
|
498 |
+
* Protect the upload dir on activation.
|
499 |
+
*
|
500 |
+
* @access public
|
501 |
+
* @return void
|
502 |
+
*/
|
503 |
+
public function directory_protection() {
|
504 |
+
|
505 |
+
// Install files and folders for uploading files and prevent hotlinking
|
506 |
+
$upload_dir = wp_upload_dir();
|
507 |
+
|
508 |
+
$files = array(
|
509 |
+
array(
|
510 |
+
'base' => $upload_dir['basedir'] . '/dlm_uploads',
|
511 |
+
'file' => '.htaccess',
|
512 |
+
'content' => 'deny from all'
|
513 |
+
),
|
514 |
+
array(
|
515 |
+
'base' => $upload_dir['basedir'] . '/dlm_uploads',
|
516 |
+
'file' => 'index.html',
|
517 |
+
'content' => ''
|
518 |
+
)
|
519 |
+
);
|
520 |
+
|
521 |
+
foreach ( $files as $file ) {
|
522 |
+
if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
|
523 |
+
if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
|
524 |
+
fwrite( $file_handle, $file['content'] );
|
525 |
+
fclose( $file_handle );
|
526 |
+
}
|
527 |
+
}
|
528 |
+
}
|
529 |
+
}
|
530 |
+
}
|
531 |
+
|
532 |
+
/**
|
533 |
+
* Init download_monitor class
|
534 |
+
*/
|
535 |
+
$GLOBALS['download_monitor'] = new WP_DLM();
|
includes/admin/class-dlm-admin-cpt.php
ADDED
@@ -0,0 +1,305 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* DLM_Admin_CPT class.
|
7 |
+
*/
|
8 |
+
class DLM_Admin_CPT {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* __construct function.
|
12 |
+
*
|
13 |
+
* @access public
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
public function __construct() {
|
17 |
+
add_action( "restrict_manage_posts", array( $this, "downloads_by_category" ) );
|
18 |
+
add_action( 'delete_post', array( $this, 'delete_post' ) );
|
19 |
+
add_filter( 'enter_title_here', array( $this, 'enter_title_here' ), 1, 2 );
|
20 |
+
add_filter( 'manage_edit-dlm_download_columns', array( $this, 'columns' ) );
|
21 |
+
add_action( 'manage_dlm_download_posts_custom_column', array( $this, 'custom_columns' ), 2 );
|
22 |
+
add_filter( 'post_updated_messages', array( $this, 'post_updated_messages' ) );
|
23 |
+
add_filter( 'manage_edit-dlm_download_sortable_columns', array( $this, 'sortable_columns' ) );
|
24 |
+
add_filter( 'request', array( $this, 'sort_columns' ) );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* downloads_by_category function.
|
29 |
+
*
|
30 |
+
* @access public
|
31 |
+
* @param int $show_counts (default: 1)
|
32 |
+
* @param int $hierarchical (default: 1)
|
33 |
+
* @param int $show_uncategorized (default: 1)
|
34 |
+
* @param string $orderby (default: '')
|
35 |
+
* @return void
|
36 |
+
*/
|
37 |
+
public function downloads_by_category( $show_counts = 1, $hierarchical = 1, $show_uncategorized = 1, $orderby = '' ) {
|
38 |
+
global $typenow, $wp_query;
|
39 |
+
|
40 |
+
if ( $typenow != 'dlm_download' )
|
41 |
+
return;
|
42 |
+
|
43 |
+
include_once( 'class-dlm-category-walker.php' );
|
44 |
+
|
45 |
+
$r = array();
|
46 |
+
$r['pad_counts'] = 1;
|
47 |
+
$r['hierarchical'] = $hierarchical;
|
48 |
+
$r['hide_empty'] = 1;
|
49 |
+
$r['show_count'] = $show_counts;
|
50 |
+
$r['selected'] = ( isset( $wp_query->query['dlm_download_category'] ) ) ? $wp_query->query['dlm_download_category'] : '';
|
51 |
+
|
52 |
+
$r['menu_order'] = false;
|
53 |
+
|
54 |
+
if ( $orderby == 'order' )
|
55 |
+
$r['menu_order'] = 'asc';
|
56 |
+
elseif ( $orderby )
|
57 |
+
$r['orderby'] = $orderby;
|
58 |
+
|
59 |
+
$terms = get_terms( 'dlm_download_category', $r );
|
60 |
+
|
61 |
+
if (!$terms) return;
|
62 |
+
|
63 |
+
$output = "<select name='dlm_download_category' id='dropdown_dlm_download_category'>";
|
64 |
+
$output .= '<option value="" ' . selected( isset( $_GET['dlm_download_category'] ) ? $_GET['dlm_download_category'] : '', '', false ) . '>'.__( 'Select a category', 'download_monitor' ).'</option>';
|
65 |
+
$output .= $this->walk_category_dropdown_tree( $terms, 0, $r );
|
66 |
+
$output .="</select>";
|
67 |
+
|
68 |
+
echo $output;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Walk the Product Categories.
|
73 |
+
*
|
74 |
+
* @access public
|
75 |
+
* @return void
|
76 |
+
*/
|
77 |
+
private function walk_category_dropdown_tree() {
|
78 |
+
$args = func_get_args();
|
79 |
+
|
80 |
+
// the user's options are the third parameter
|
81 |
+
if ( empty($args[2]['walker']) || !is_a($args[2]['walker'], 'Walker') )
|
82 |
+
$walker = new DLM_Category_Walker;
|
83 |
+
else
|
84 |
+
$walker = $args[2]['walker'];
|
85 |
+
|
86 |
+
return call_user_func_array( array( $walker, 'walk' ), $args );
|
87 |
+
}
|
88 |
+
/**
|
89 |
+
* delete_post function.
|
90 |
+
*
|
91 |
+
* @access public
|
92 |
+
* @param mixed $id
|
93 |
+
* @return void
|
94 |
+
*/
|
95 |
+
public function delete_post( $id ) {
|
96 |
+
global $wpdb;
|
97 |
+
|
98 |
+
if ( ! current_user_can( 'delete_posts' ) )
|
99 |
+
return;
|
100 |
+
|
101 |
+
if ( $id > 0 ) {
|
102 |
+
|
103 |
+
$post_type = get_post_type( $id );
|
104 |
+
|
105 |
+
switch( $post_type ) {
|
106 |
+
case 'dlm_download' :
|
107 |
+
if ( $versions =& get_children( 'post_parent=' . $id . '&post_type=dlm_download_version' ) )
|
108 |
+
if ( $versions )
|
109 |
+
foreach ( $versions as $child )
|
110 |
+
wp_delete_post( $child->ID, true );
|
111 |
+
break;
|
112 |
+
}
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* enter_title_here function.
|
118 |
+
*
|
119 |
+
* @access public
|
120 |
+
* @return void
|
121 |
+
*/
|
122 |
+
public function enter_title_here( $text, $post ) {
|
123 |
+
if ( $post->post_type == 'dlm_download' )
|
124 |
+
return __( 'Download title', 'download_monitor' );
|
125 |
+
return $text;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* post_updated_messages function.
|
130 |
+
*
|
131 |
+
* @access public
|
132 |
+
* @param mixed $messages
|
133 |
+
* @return void
|
134 |
+
*/
|
135 |
+
public function post_updated_messages( $messages ) {
|
136 |
+
global $post, $post_ID;
|
137 |
+
|
138 |
+
$messages['dlm_download'] = array(
|
139 |
+
0 => '', // Unused. Messages start at index 1.
|
140 |
+
1 => __('Download updated.', 'download_monitor'),
|
141 |
+
2 => __('Custom field updated.', 'download_monitor'),
|
142 |
+
3 => __('Custom field deleted.', 'download_monitor'),
|
143 |
+
4 => __('Download updated.', 'download_monitor'),
|
144 |
+
5 => isset($_GET['revision']) ? sprintf( __('Download restored to revision from %s', 'download_monitor'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
|
145 |
+
6 => __('Download published.', 'download_monitor'),
|
146 |
+
7 => __('Download saved.', 'download_monitor'),
|
147 |
+
8 => __('Download submitted.', 'download_monitor'),
|
148 |
+
9 => sprintf( __('Download scheduled for: <strong>%1$s</strong>.', 'download_monitor'),
|
149 |
+
date_i18n( __( 'M j, Y @ G:i', 'download_monitor' ), strtotime( $post->post_date ) ) ),
|
150 |
+
10 => __('Download draft updated.', 'download_monitor'),
|
151 |
+
);
|
152 |
+
|
153 |
+
return $messages;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* columns function.
|
158 |
+
*
|
159 |
+
* @access public
|
160 |
+
* @param mixed $columns
|
161 |
+
* @return void
|
162 |
+
*/
|
163 |
+
public function columns( $columns ) {
|
164 |
+
global $download_monitor;
|
165 |
+
|
166 |
+
$columns = array();
|
167 |
+
|
168 |
+
$columns["cb"] = "<input type=\"checkbox\" />";
|
169 |
+
$columns["thumb"] = __("Image", 'download_monitor');
|
170 |
+
$columns["title"] = __("Title", 'download_monitor');
|
171 |
+
$columns["id"] = __("ID", 'download_monitor');
|
172 |
+
$columns["file"] = __("File", 'download_monitor');
|
173 |
+
$columns["version"] = __("Version", 'download_monitor');
|
174 |
+
$columns["download_cat"] = __("Categories", 'download_monitor');
|
175 |
+
$columns["download_tag"] = __("Tags", 'download_monitor');
|
176 |
+
|
177 |
+
$columns["download_count"] = '<img src="' . $download_monitor->plugin_url() . '/assets/images/download_count_head.png" alt="' . __("download_count", 'download_monitor') . '" />';
|
178 |
+
$columns["featured"] = '<img src="' . $download_monitor->plugin_url() . '/assets/images/featured_head.png" alt="' . __("Featured", 'download_monitor') . '" />';
|
179 |
+
$columns["members_only"] = '<img src="' . $download_monitor->plugin_url() . '/assets/images/member_head.png" alt="' . __("Members only", 'download_monitor') . '" />';
|
180 |
+
|
181 |
+
$columns["date"] = __("Date posted", 'download_monitor');
|
182 |
+
|
183 |
+
return $columns;
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* custom_columns function.
|
188 |
+
*
|
189 |
+
* @access public
|
190 |
+
* @param mixed $column
|
191 |
+
* @return void
|
192 |
+
*/
|
193 |
+
public function custom_columns( $column ) {
|
194 |
+
global $post, $download_monitor;
|
195 |
+
|
196 |
+
$download = new DLM_Download( $post->ID );
|
197 |
+
$file = $download->get_file_version();
|
198 |
+
|
199 |
+
switch ($column) {
|
200 |
+
case "thumb" :
|
201 |
+
echo $download->get_the_image();
|
202 |
+
break;
|
203 |
+
case "id" :
|
204 |
+
echo $post->ID;
|
205 |
+
break;
|
206 |
+
case "download_cat" :
|
207 |
+
if ( ! $terms = get_the_term_list( $post->ID, 'dlm_download_category', '', ', ', '' ) ) echo '<span class="na">–</span>'; else echo $terms;
|
208 |
+
break;
|
209 |
+
case "download_tag" :
|
210 |
+
if ( ! $terms = get_the_term_list( $post->ID, 'dlm_download_tag', '', ', ', '' ) ) echo '<span class="na">–</span>'; else echo $terms;
|
211 |
+
break;
|
212 |
+
case "featured" :
|
213 |
+
|
214 |
+
if ( $download->is_featured() )
|
215 |
+
echo '<img src="' . $download_monitor->plugin_url() . '/assets/images/on.png" alt="yes" />';
|
216 |
+
else
|
217 |
+
echo '<span class="na">–</span>';
|
218 |
+
|
219 |
+
break;
|
220 |
+
case "members_only" :
|
221 |
+
|
222 |
+
if ( $download->is_members_only() )
|
223 |
+
echo '<img src="' . $download_monitor->plugin_url() . '/assets/images/on.png" alt="yes" />';
|
224 |
+
else
|
225 |
+
echo '<span class="na">–</span>';
|
226 |
+
|
227 |
+
break;
|
228 |
+
case "file" :
|
229 |
+
if ( $file )
|
230 |
+
echo '<code>' . $file->filename . '</code>';
|
231 |
+
else
|
232 |
+
echo '<span class="na">–</span>';
|
233 |
+
break;
|
234 |
+
case "version" :
|
235 |
+
if ( $file )
|
236 |
+
echo $file->version;
|
237 |
+
else
|
238 |
+
echo '<span class="na">–</span>';
|
239 |
+
break;
|
240 |
+
case "download_count" :
|
241 |
+
echo number_format( $download->get_the_download_count(), 0, '.', ',' );
|
242 |
+
break;
|
243 |
+
case "featured" :
|
244 |
+
|
245 |
+
if ( $download->is_featured() )
|
246 |
+
echo '<img src="' . $download_monitor->plugin_url() . '/assets/images/on.png" alt="yes" />';
|
247 |
+
else
|
248 |
+
echo '<span class="na">–</span>';
|
249 |
+
|
250 |
+
break;
|
251 |
+
}
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* sortable_columns function.
|
256 |
+
*
|
257 |
+
* @access public
|
258 |
+
* @param mixed $columns
|
259 |
+
* @return void
|
260 |
+
*/
|
261 |
+
public function sortable_columns( $columns ) {
|
262 |
+
$custom = array(
|
263 |
+
'id' => 'id',
|
264 |
+
'download_count' => 'download_count',
|
265 |
+
'featured' => 'featured',
|
266 |
+
'members_only' => 'members_only',
|
267 |
+
);
|
268 |
+
return wp_parse_args( $custom, $columns );
|
269 |
+
}
|
270 |
+
|
271 |
+
/**
|
272 |
+
* sort_columns function.
|
273 |
+
*
|
274 |
+
* @access public
|
275 |
+
* @param mixed $vars
|
276 |
+
* @return void
|
277 |
+
*/
|
278 |
+
public function sort_columns( $vars ) {
|
279 |
+
if ( isset( $vars['orderby'] ) ) {
|
280 |
+
if ( 'id' == $vars['orderby'] )
|
281 |
+
$vars['orderby'] = 'ID';
|
282 |
+
|
283 |
+
elseif ( 'download_count' == $vars['orderby'] )
|
284 |
+
$vars = array_merge( $vars, array(
|
285 |
+
'meta_key' => '_download_count',
|
286 |
+
'orderby' => 'meta_value_num'
|
287 |
+
) );
|
288 |
+
|
289 |
+
elseif ( 'featured' == $vars['orderby'] )
|
290 |
+
$vars = array_merge( $vars, array(
|
291 |
+
'meta_key' => '_featured',
|
292 |
+
'orderby' => 'meta_value'
|
293 |
+
) );
|
294 |
+
|
295 |
+
elseif ( 'members_only' == $vars['orderby'] )
|
296 |
+
$vars = array_merge( $vars, array(
|
297 |
+
'meta_key' => '_members_only',
|
298 |
+
'orderby' => 'meta_value'
|
299 |
+
) );
|
300 |
+
}
|
301 |
+
return $vars;
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
new DLM_Admin_CPT();
|
includes/admin/class-dlm-admin-dashboard.php
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* DLM_Admin_Dashboard class.
|
7 |
+
*/
|
8 |
+
class DLM_Admin_Dashboard {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* __construct function.
|
12 |
+
*
|
13 |
+
* @access public
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
public function __construct() {
|
17 |
+
|
18 |
+
if ( ! current_user_can( 'manage_options' ) )
|
19 |
+
return;
|
20 |
+
|
21 |
+
wp_add_dashboard_widget( 'dlm_popular_downloads', __( 'Popular Downloads', 'download_monitor' ), array( $this, 'popular_downloads' ) );
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* popular_downloads function.
|
26 |
+
*
|
27 |
+
* @access public
|
28 |
+
* @return void
|
29 |
+
*/
|
30 |
+
public function popular_downloads() {
|
31 |
+
|
32 |
+
$args = array(
|
33 |
+
'post_status' => 'publish',
|
34 |
+
'post_type' => 'dlm_download',
|
35 |
+
'no_found_rows' => 1,
|
36 |
+
'posts_per_page' => 10,
|
37 |
+
'orderby' => 'meta_value',
|
38 |
+
'order' => 'desc',
|
39 |
+
'meta_query' => array(
|
40 |
+
array(
|
41 |
+
'key' => '_download_count',
|
42 |
+
'value' => '0',
|
43 |
+
'compare' => '>'
|
44 |
+
)
|
45 |
+
),
|
46 |
+
'meta_key' => '_download_count',
|
47 |
+
'fields' => 'ids'
|
48 |
+
);
|
49 |
+
|
50 |
+
$download_ids = get_posts( $args );
|
51 |
+
|
52 |
+
if ( empty( $download_ids ) )
|
53 |
+
echo '<p>' . __( 'There are no stats available yet!', 'download_monitor' ) . '</p>';
|
54 |
+
|
55 |
+
$downloads = array();
|
56 |
+
|
57 |
+
foreach ( $download_ids as $download_id ) {
|
58 |
+
$downloads[ $download_id ] = get_post_meta( $download_id, '_download_count', true );
|
59 |
+
}
|
60 |
+
|
61 |
+
$max_count = max( $downloads );
|
62 |
+
|
63 |
+
?>
|
64 |
+
<table class="download_chart" cellpadding="0" cellspacing="0">
|
65 |
+
<thead>
|
66 |
+
<tr>
|
67 |
+
<th scope="col"><?php _e( 'Download', "download_monitor" ); ?></th>
|
68 |
+
<th scope="col"><?php _e( 'Download count', "download_monitor" ); ?></th>
|
69 |
+
</tr>
|
70 |
+
</thead>
|
71 |
+
<tbody>
|
72 |
+
<?php
|
73 |
+
foreach ( $downloads as $download_id => $count ) {
|
74 |
+
$download = new DLM_Download( $download_id );
|
75 |
+
|
76 |
+
$width = $count / ( $max_count ? $max_count : 1 ) * 67;
|
77 |
+
|
78 |
+
echo '<tr>
|
79 |
+
<th scope="row" style="width:25%;"><a href="' . admin_url( 'post.php?post=' . $download_id . '&action=edit' ) . '">' . $download->get_the_title() . '</a></th>
|
80 |
+
<td><span class="bar" style="width:' . $width . '%;"></span>' . number_format( $count, 0, '.', ',' ) . '</td>
|
81 |
+
</tr>';
|
82 |
+
}
|
83 |
+
?>
|
84 |
+
</tbody>
|
85 |
+
</table>
|
86 |
+
<?php
|
87 |
+
}
|
88 |
+
|
89 |
+
}
|
90 |
+
|
91 |
+
new DLM_Admin_Dashboard();
|
includes/admin/class-dlm-admin-insert.php
ADDED
@@ -0,0 +1,350 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
3 |
+
|
4 |
+
/**
|
5 |
+
* DLM_Admin_Insert class.
|
6 |
+
*/
|
7 |
+
class DLM_Admin_Insert {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* __construct function.
|
11 |
+
*
|
12 |
+
* @access public
|
13 |
+
* @return void
|
14 |
+
*/
|
15 |
+
public function __construct() {
|
16 |
+
add_action( 'media_buttons', array( $this, 'media_buttons' ), 20 );
|
17 |
+
add_action( 'media_upload_add_download', array( $this, 'media_browser' ) );
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* media_buttons function.
|
22 |
+
*
|
23 |
+
* @access public
|
24 |
+
* @return void
|
25 |
+
*/
|
26 |
+
public function media_buttons( $editor_id = 'content' ) {
|
27 |
+
global $download_monitor, $post;
|
28 |
+
|
29 |
+
if ( ! isset( $post->post_type ) || ! in_array( $post->post_type, array( 'post', 'page' ) ) )
|
30 |
+
return;
|
31 |
+
|
32 |
+
echo '<a href="#" class="button insert-download add_download" data-editor="' . esc_attr( $editor_id ) . '" title="' . esc_attr__( 'Insert Download', 'download_monitor' ) . '">' . __( 'Insert Download', 'download_monitor' ) . '</a>';
|
33 |
+
|
34 |
+
ob_start();
|
35 |
+
?>
|
36 |
+
jQuery(function(){
|
37 |
+
// Browse for file
|
38 |
+
jQuery('body').on('click', 'a.add_download', function(e){
|
39 |
+
|
40 |
+
tb_show('<?php esc_attr_e( 'Insert Download', 'download_monitor' ); ?>', 'media-upload.php?post_id=<?php echo $post->ID; ?>&type=add_download&from=wpdlm01&TB_iframe=true&height=200');
|
41 |
+
|
42 |
+
return false;
|
43 |
+
});
|
44 |
+
});
|
45 |
+
<?php
|
46 |
+
|
47 |
+
$js_code = ob_get_clean();
|
48 |
+
$download_monitor->add_inline_js( $js_code );
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* media_browser function.
|
53 |
+
*
|
54 |
+
* @access public
|
55 |
+
* @return void
|
56 |
+
*/
|
57 |
+
public function media_browser() {
|
58 |
+
global $download_monitor;
|
59 |
+
|
60 |
+
// Enqueue scripts and styles for panel
|
61 |
+
wp_enqueue_script( 'chosen', $download_monitor->plugin_url() . '/assets/js/chosen/chosen.jquery.min.js' );
|
62 |
+
wp_enqueue_style( 'chosen', $download_monitor->plugin_url() . '/assets/js/chosen/chosen.css' );
|
63 |
+
wp_enqueue_style( 'download_monitor_admin_css', $download_monitor->plugin_url() . '/assets/css/admin.css' );
|
64 |
+
|
65 |
+
wp_enqueue_script( 'common' );
|
66 |
+
wp_enqueue_style( 'global' );
|
67 |
+
wp_enqueue_style( 'wp-admin' );
|
68 |
+
wp_enqueue_style( 'colors' );
|
69 |
+
wp_enqueue_script('plupload-all');
|
70 |
+
|
71 |
+
echo '<!DOCTYPE html><html lang="en"><head><title>' . __( 'Insert Download', 'download_monitor' ) . '</title><meta charset="utf-8" />';
|
72 |
+
|
73 |
+
do_action( 'admin_print_styles' );
|
74 |
+
do_action( 'admin_print_scripts' );
|
75 |
+
do_action( 'admin_head' );
|
76 |
+
|
77 |
+
echo '<body id="insert-download" class="wp-core-ui">';
|
78 |
+
|
79 |
+
?>
|
80 |
+
<h2 class="nav-tab-wrapper">
|
81 |
+
<a href="#insert-shortcode" class="nav-tab nav-tab-active"><?php _e( 'Insert Shortcode', 'download_monitor' ); ?></a><a href="#quick-add" class="nav-tab"><?php _e( 'Quick-add download', 'download_monitor' ); ?></a>
|
82 |
+
</h2>
|
83 |
+
<?php
|
84 |
+
|
85 |
+
// Handle quick-add form
|
86 |
+
if ( ! empty( $_POST['download_url'] ) && ! empty( $_POST['download_title'] ) && wp_verify_nonce( $_POST['quick-add-nonce'], 'quick-add') ) {
|
87 |
+
|
88 |
+
$url = stripslashes( $_POST['download_url'] );
|
89 |
+
$title = sanitize_text_field( stripslashes( $_POST['download_title'] ) );
|
90 |
+
$version = sanitize_text_field( stripslashes( $_POST['download_version'] ) );
|
91 |
+
|
92 |
+
try {
|
93 |
+
|
94 |
+
$download = array(
|
95 |
+
'post_title' => $title,
|
96 |
+
'post_content' => '',
|
97 |
+
'post_status' => 'publish',
|
98 |
+
'post_author' => get_current_user_id(),
|
99 |
+
'post_type' => 'dlm_download'
|
100 |
+
);
|
101 |
+
|
102 |
+
$download_id = wp_insert_post( $download );
|
103 |
+
|
104 |
+
if ( $download_id ) {
|
105 |
+
|
106 |
+
// Meta
|
107 |
+
update_post_meta( $download_id, '_featured', 'no' );
|
108 |
+
update_post_meta( $download_id, '_members_only', 'no' );
|
109 |
+
update_post_meta( $download_id, '_download_count', 0 );
|
110 |
+
|
111 |
+
// File
|
112 |
+
$file = array(
|
113 |
+
'post_title' => 'Download #' . $download_id . ' File Version',
|
114 |
+
'post_content' => '',
|
115 |
+
'post_status' => 'publish',
|
116 |
+
'post_author' => get_current_user_id(),
|
117 |
+
'post_parent' => $download_id,
|
118 |
+
'post_type' => 'dlm_download_version'
|
119 |
+
);
|
120 |
+
|
121 |
+
$file_id = wp_insert_post( $file );
|
122 |
+
|
123 |
+
if ( ! $file_id )
|
124 |
+
throw new Exception( __( 'Error: File was not created.', 'download_monitor' ) );
|
125 |
+
|
126 |
+
// Meta
|
127 |
+
update_post_meta( $file_id, '_version', $version );
|
128 |
+
update_post_meta( $file_id, '_files', array( $url ) );
|
129 |
+
|
130 |
+
$filesize = null;
|
131 |
+
|
132 |
+
if ( file_exists( $url ) && ( $filesize = filesize( $url ) ) )
|
133 |
+
$filesize = $filesize;
|
134 |
+
else {
|
135 |
+
$file = wp_remote_head( $url );
|
136 |
+
|
137 |
+
if ( ! is_wp_error( $file ) && ! empty( $file['headers']['content-length'] ) )
|
138 |
+
$filesize = $file['headers']['content-length'];
|
139 |
+
}
|
140 |
+
|
141 |
+
update_post_meta( $file_id, '_filesize', $filesize );
|
142 |
+
|
143 |
+
echo '<div class="updated"><p>' . __( 'Download successfully created.', 'download_monitor' ) . '</p></div>';
|
144 |
+
|
145 |
+
} else throw new Exception( __( 'Error: Download was not created.', 'download_monitor' ) );
|
146 |
+
|
147 |
+
} catch ( Exception $e ) {
|
148 |
+
echo '<div class="error"><p>' . $e->getMessage() . "</p></div>";
|
149 |
+
}
|
150 |
+
|
151 |
+
}
|
152 |
+
|
153 |
+
// Get all downloads
|
154 |
+
$downloads = get_posts( array(
|
155 |
+
'post_status' => 'publish',
|
156 |
+
'post_type' => 'dlm_download',
|
157 |
+
'posts_per_page' => -1
|
158 |
+
) );
|
159 |
+
?>
|
160 |
+
<form id="insert-shortcode">
|
161 |
+
|
162 |
+
<p>
|
163 |
+
<label for="download_id"><?php _e( 'Choose a download', 'download_monitor' ); ?>:</label>
|
164 |
+
<select id="download_id" class="input">
|
165 |
+
<?php
|
166 |
+
foreach ( $downloads as $download ) {
|
167 |
+
$download = new DLM_Download( $download->ID );
|
168 |
+
|
169 |
+
echo '<option value="' . $download->id . '">#' . $download->id . ' – ' . $download->get_the_title() . ' – ' . $download->get_the_filename() .'</option>';
|
170 |
+
}
|
171 |
+
?>
|
172 |
+
</select>
|
173 |
+
</p>
|
174 |
+
<p>
|
175 |
+
<label for="template_name"><?php _e( 'Template', 'download_monitor' ); ?>:</label>
|
176 |
+
<input type="text" id="template_name" value="" class="input" placeholder="<?php _e( 'Template Name', 'download_monitor' ); ?>" />
|
177 |
+
<span class="description">
|
178 |
+
<?php _e( 'Leaving this blank will use the default <code>content-download.php</code> template file. If you enter, for example, <code>image</code>, the <code>content-download-image.php</code> template will be used instead.', 'download_monitor' ); ?>
|
179 |
+
</span>
|
180 |
+
</p>
|
181 |
+
<p>
|
182 |
+
<input type="button" class="button insert_download button-primary button-large" value="<?php _e( 'Insert Shortcode', 'download_monitor' ); ?>" />
|
183 |
+
</p>
|
184 |
+
|
185 |
+
</form>
|
186 |
+
|
187 |
+
<form id="quick-add" action="" method="post">
|
188 |
+
|
189 |
+
<!-- Uploader section -->
|
190 |
+
<div id="plupload-upload-ui" class="hide-if-no-js">
|
191 |
+
<div id="drag-drop-area" style="height:240px">
|
192 |
+
<div class="drag-drop-inside">
|
193 |
+
<p class="drag-drop-info"><?php _e( 'Drop file here', 'download_monitor' ); ?></p>
|
194 |
+
<p><?php _e( 'or', 'download_monitor' ); ?></p>
|
195 |
+
<p class="drag-drop-buttons"><input id="plupload-browse-button" type="button" value="<?php esc_attr_e( 'Select File', 'download_monitor' ); ?>" class="button" /></p>
|
196 |
+
<p><?php _e( 'or', 'download_monitor' ); ?></p>
|
197 |
+
<p><a href="#" class="add_manually"><?php _e( 'Enter URL manually', 'download_monitor' ); ?></a></p>
|
198 |
+
</div>
|
199 |
+
</div>
|
200 |
+
</div>
|
201 |
+
<div id="quick-add-details" style="display:none">
|
202 |
+
<p>
|
203 |
+
<label for="download_url"><?php _e( 'Download URL', 'download_monitor' ); ?>:</label>
|
204 |
+
<input type="text" name="download_url" id="download_url" value="" class="download_url input" placeholder="<?php _e( 'Required URL', 'download_monitor' ); ?>" />
|
205 |
+
</p>
|
206 |
+
<p>
|
207 |
+
<label for="download_title"><?php _e( 'Download Title', 'download_monitor' ); ?>:</label>
|
208 |
+
<input type="text" name="download_title" id="download_title" value="" class="download_title input" placeholder="<?php _e( 'Required title', 'download_monitor' ); ?>" />
|
209 |
+
</p>
|
210 |
+
<p>
|
211 |
+
<label for="download_version"><?php _e( 'Version', 'download_monitor' ); ?>:</label>
|
212 |
+
<input type="text" name="download_version" id="download_version" value="" class="input" placeholder="<?php _e( 'Optional version number', 'download_monitor' ); ?>" />
|
213 |
+
</p>
|
214 |
+
<p>
|
215 |
+
<input type="submit" class="button button-primary button-large" value="<?php _e( 'Save Download', 'download_monitor' ); ?>" />
|
216 |
+
<?php wp_nonce_field( 'quick-add', 'quick-add-nonce' ) ?>
|
217 |
+
</p>
|
218 |
+
</div>
|
219 |
+
|
220 |
+
</form>
|
221 |
+
|
222 |
+
<script type="text/javascript">
|
223 |
+
jQuery(function() {
|
224 |
+
|
225 |
+
jQuery('.nav-tab-wrapper a').click(function() {
|
226 |
+
jQuery('#insert-shortcode, #quick-add').hide();
|
227 |
+
jQuery(jQuery(this).attr('href')).show();
|
228 |
+
jQuery('a.nav-tab-active').removeClass('nav-tab-active');
|
229 |
+
jQuery(this).addClass('nav-tab-active');
|
230 |
+
return false;
|
231 |
+
});
|
232 |
+
|
233 |
+
jQuery('#quick-add').hide();
|
234 |
+
|
235 |
+
jQuery('#download_id').chosen();
|
236 |
+
|
237 |
+
jQuery('body').on('click', '.insert_download', function(){
|
238 |
+
|
239 |
+
var win = window.dialogArguments || opener || parent || top;
|
240 |
+
|
241 |
+
var download_id = jQuery('#download_id').val();
|
242 |
+
var template = jQuery('#template_name').val();
|
243 |
+
var shortcode = '[download id="' + jQuery('#download_id').val() + '"';
|
244 |
+
|
245 |
+
if ( template )
|
246 |
+
shortcode = shortcode + ' template="' + template + '"';
|
247 |
+
|
248 |
+
shortcode = shortcode + ']';
|
249 |
+
|
250 |
+
win.send_to_editor( shortcode );
|
251 |
+
|
252 |
+
return false;
|
253 |
+
});
|
254 |
+
|
255 |
+
jQuery('.add_manually').click(function() {
|
256 |
+
jQuery('#plupload-upload-ui').slideUp();
|
257 |
+
jQuery('#quick-add-details').slideDown();
|
258 |
+
return false;
|
259 |
+
});
|
260 |
+
|
261 |
+
<?php
|
262 |
+
$plupload_init = array(
|
263 |
+
'runtimes' => 'html5,silverlight,flash,html4',
|
264 |
+
'browse_button' => 'plupload-browse-button',
|
265 |
+
'container' => 'plupload-upload-ui',
|
266 |
+
'drop_element' => 'drag-drop-area',
|
267 |
+
'file_data_name' => 'async-upload',
|
268 |
+
'multiple_queues' => false,
|
269 |
+
'max_file_size' => wp_max_upload_size() . 'b',
|
270 |
+
'url' => admin_url( 'admin-ajax.php' ),
|
271 |
+
'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ),
|
272 |
+
'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ),
|
273 |
+
'filters' => array( array( 'title' => __( 'Allowed Files' ), 'extensions' => '*' ) ),
|
274 |
+
'multipart' => true,
|
275 |
+
'urlstream_upload' => true,
|
276 |
+
|
277 |
+
// additional post data to send to our ajax hook
|
278 |
+
'multipart_params' => array(
|
279 |
+
'_ajax_nonce' => wp_create_nonce( 'file-upload' ),
|
280 |
+
'action' => 'download_monitor_insert_panel_upload',
|
281 |
+
'type' => 'dlm_download'
|
282 |
+
),
|
283 |
+
);
|
284 |
+
|
285 |
+
// we should probably not apply this filter, plugins may expect wp's media uploader...
|
286 |
+
$plupload_init = apply_filters('plupload_init', $plupload_init);
|
287 |
+
?>
|
288 |
+
|
289 |
+
// create the uploader and pass the config from above
|
290 |
+
var uploader = new plupload.Uploader(<?php echo json_encode( $plupload_init ); ?>);
|
291 |
+
|
292 |
+
// checks if browser supports drag and drop upload, makes some css adjustments if necessary
|
293 |
+
uploader.bind('Init', function(up){
|
294 |
+
var uploaddiv = jQuery('#plupload-upload-ui');
|
295 |
+
|
296 |
+
if ( up.features.dragdrop ) {
|
297 |
+
uploaddiv.addClass('drag-drop');
|
298 |
+
|
299 |
+
jQuery('#drag-drop-area')
|
300 |
+
.bind('dragover.wp-uploader', function() {
|
301 |
+
uploaddiv.addClass('drag-over');
|
302 |
+
})
|
303 |
+
.bind('dragleave.wp-uploader, drop.wp-uploader', function() {
|
304 |
+
uploaddiv.removeClass('drag-over');
|
305 |
+
});
|
306 |
+
|
307 |
+
} else {
|
308 |
+
uploaddiv.removeClass('drag-drop');
|
309 |
+
jQuery('#drag-drop-area').unbind('.wp-uploader');
|
310 |
+
}
|
311 |
+
});
|
312 |
+
|
313 |
+
uploader.init();
|
314 |
+
|
315 |
+
// a file was added in the queue
|
316 |
+
uploader.bind('FilesAdded', function(up, files) {
|
317 |
+
var hundredmb = 100 * 1024 * 1024, max = parseInt(up.settings.max_file_size, 10);
|
318 |
+
|
319 |
+
plupload.each(files, function(file) {
|
320 |
+
if ( max > hundredmb && file.size > hundredmb && up.runtime != 'html5' ) {
|
321 |
+
// file size error?
|
322 |
+
} else {
|
323 |
+
jQuery('.drag-drop-inside').html('<p><?php _e( 'Please wait...', 'download_monitor' ); ?></p>');
|
324 |
+
}
|
325 |
+
});
|
326 |
+
|
327 |
+
up.refresh();
|
328 |
+
up.start();
|
329 |
+
});
|
330 |
+
|
331 |
+
// a file was uploaded
|
332 |
+
uploader.bind('FileUploaded', function( up, file, response ) {
|
333 |
+
jQuery('#quick-add-details').find('input.download_url').val( response.response );
|
334 |
+
jQuery('#quick-add-details').find('input.download_title').val( basename( response.response ) );
|
335 |
+
jQuery('#plupload-upload-ui').slideUp();
|
336 |
+
jQuery('#quick-add-details').slideDown();
|
337 |
+
});
|
338 |
+
|
339 |
+
function basename(path) {
|
340 |
+
return path.split('/').reverse()[0];
|
341 |
+
}
|
342 |
+
|
343 |
+
});
|
344 |
+
</script>
|
345 |
+
<?php
|
346 |
+
echo '</body></html>';
|
347 |
+
}
|
348 |
+
}
|
349 |
+
|
350 |
+
new DLM_Admin_Insert();
|
includes/admin/class-dlm-admin-media-browser.php
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* DLM_Admin_Media_Browser class.
|
7 |
+
*/
|
8 |
+
class DLM_Admin_Media_Browser {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* __construct function.
|
12 |
+
*
|
13 |
+
* @access public
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
public function __construct() {
|
17 |
+
add_action( 'media_upload_downloadable_file_browser', array( $this, 'media_browser' ) );
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* media_browser function.
|
22 |
+
*
|
23 |
+
* @access public
|
24 |
+
* @return void
|
25 |
+
*/
|
26 |
+
public function media_browser() {
|
27 |
+
global $download_monitor;
|
28 |
+
|
29 |
+
$files = $download_monitor->list_files( ABSPATH, 1 );
|
30 |
+
|
31 |
+
echo '<!DOCTYPE html><html lang="en"><head><title>' . __( 'Browse for a file', 'download_monitor' ) . '</title>';
|
32 |
+
|
33 |
+
do_action( 'admin_print_styles' );
|
34 |
+
do_action( 'admin_print_scripts' );
|
35 |
+
do_action( 'admin_head' );
|
36 |
+
|
37 |
+
echo '<meta charset="utf-8" /><link rel="stylesheet" type="text/css" href="' . $download_monitor->plugin_url() . '/assets/css/admin.css" /></head><body>';
|
38 |
+
|
39 |
+
echo '<ul class="download_monitor_file_browser">';
|
40 |
+
|
41 |
+
foreach( $files as $found_file ) {
|
42 |
+
|
43 |
+
$file = pathinfo( $found_file['path'] );
|
44 |
+
|
45 |
+
if ( $found_file['type'] == 'folder' ) {
|
46 |
+
|
47 |
+
echo '<li><a href="#" class="folder" data-path="' . trailingslashit( $file['dirname'] ) . $file['basename'] . '">' . $file['basename'] . '</a></li>';
|
48 |
+
|
49 |
+
} else {
|
50 |
+
|
51 |
+
$filename = $file['basename'];
|
52 |
+
$extension = ( empty( $file['extension'] ) ) ? '' : $file['extension'];
|
53 |
+
|
54 |
+
if ( substr( $filename, 0, 1 ) == '.' ) continue; // Ignore files starting with . like htaccess
|
55 |
+
if ( in_array( $extension, array( '', 'php', 'html', 'htm', 'tmp' ) ) ) continue; // Ignored file types
|
56 |
+
|
57 |
+
echo '<li><a href="#" class="file filetype-' . sanitize_title( $extension ) . '" data-path="' . trailingslashit( $file['dirname'] ) . $file['basename'] . '">' . $file['basename'] . '</a></li>';
|
58 |
+
|
59 |
+
}
|
60 |
+
|
61 |
+
}
|
62 |
+
|
63 |
+
echo '</ul>';
|
64 |
+
?>
|
65 |
+
<script type="text/javascript">
|
66 |
+
jQuery(function() {
|
67 |
+
jQuery('.download_monitor_file_browser').on('click', 'a', function(){
|
68 |
+
|
69 |
+
var $link = jQuery(this);
|
70 |
+
var $parent = $link.closest('li');
|
71 |
+
|
72 |
+
if ( $link.is('.file') ) {
|
73 |
+
|
74 |
+
var win = window.dialogArguments || opener || parent || top;
|
75 |
+
|
76 |
+
win.send_to_editor( $link.attr('data-path') );
|
77 |
+
|
78 |
+
} else if ( $link.is('.folder_open') ) {
|
79 |
+
|
80 |
+
$parent.find('ul').remove();
|
81 |
+
$link.removeClass('folder_open');
|
82 |
+
|
83 |
+
} else {
|
84 |
+
|
85 |
+
$link.after('<ul class="load_tree loading"></ul>');
|
86 |
+
|
87 |
+
var data = {
|
88 |
+
action: 'download_monitor_list_files',
|
89 |
+
path: jQuery(this).attr('data-path'),
|
90 |
+
security: '<?php echo wp_create_nonce("list-files"); ?>'
|
91 |
+
};
|
92 |
+
|
93 |
+
jQuery.post('<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) {
|
94 |
+
|
95 |
+
$link.addClass('folder_open');
|
96 |
+
|
97 |
+
if ( response ) {
|
98 |
+
$parent.find('.load_tree').html( response );
|
99 |
+
} else {
|
100 |
+
$parent.find('.load_tree').html( '<li class="nofiles"><?php _e('No files found', 'download_monitor'); ?></li>' );
|
101 |
+
}
|
102 |
+
$parent.find('.load_tree').removeClass('load_tree loading');
|
103 |
+
|
104 |
+
});
|
105 |
+
}
|
106 |
+
return false;
|
107 |
+
});
|
108 |
+
});
|
109 |
+
</script>
|
110 |
+
<?php
|
111 |
+
echo '</body></html>';
|
112 |
+
}
|
113 |
+
|
114 |
+
}
|
115 |
+
|
116 |
+
new DLM_Admin_Media_Browser();
|
includes/admin/class-dlm-admin-writepanels.php
ADDED
@@ -0,0 +1,480 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* DLM_Admin class.
|
7 |
+
*/
|
8 |
+
class DLM_Admin_Writepanels {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* __construct function.
|
12 |
+
*
|
13 |
+
* @access public
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
public function __construct() {
|
17 |
+
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
|
18 |
+
add_action( 'save_post', array( $this, 'save_post' ), 1, 2 );
|
19 |
+
add_action( 'dlm_save_meta_boxes', array( $this, 'save_meta_boxes' ), 1, 2 );
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* add_meta_boxes function.
|
24 |
+
*
|
25 |
+
* @access public
|
26 |
+
* @return void
|
27 |
+
*/
|
28 |
+
public function add_meta_boxes() {
|
29 |
+
add_meta_box( 'download-monitor-options', __( 'Download Options', 'download_monitor' ), array( $this, 'download_options' ), 'dlm_download', 'side', 'high' );
|
30 |
+
add_meta_box( 'download-monitor-file', __( 'Downloadable File Versions', 'download_monitor' ), array( $this, 'download_files' ), 'dlm_download', 'normal', 'high' );
|
31 |
+
|
32 |
+
// Excerpt
|
33 |
+
if ( function_exists('wp_editor') ) {
|
34 |
+
remove_meta_box( 'postexcerpt', 'dlm_download', 'normal' );
|
35 |
+
add_meta_box( 'postexcerpt', __('Short Description', 'download_monitor'), array( $this, 'short_description' ), 'dlm_download', 'normal', 'high' );
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* download_options function.
|
41 |
+
*
|
42 |
+
* @access public
|
43 |
+
* @param mixed $post
|
44 |
+
* @return void
|
45 |
+
*/
|
46 |
+
public function download_options( $post ) {
|
47 |
+
global $post, $thepostid;
|
48 |
+
|
49 |
+
$thepostid = $post->ID;
|
50 |
+
|
51 |
+
echo '<div class="dlm_options_panel">';
|
52 |
+
|
53 |
+
do_action( 'dlm_options_start', $thepostid );
|
54 |
+
|
55 |
+
echo '<p class="form-field form-field-checkbox">
|
56 |
+
<input type="checkbox" name="_featured" id="_featured" ' . checked( get_post_meta( $thepostid, '_featured', true ), 'yes', false ) . ' />
|
57 |
+
<label for="_featured">' . __( 'Featured download', 'download_monitor' ) . '</label>
|
58 |
+
<span class="description">' . __( 'Mark this download as featured. Used by shortcodes and widgets.', 'download_monitor' ) . '</span>
|
59 |
+
</p>';
|
60 |
+
|
61 |
+
echo '<p class="form-field form-field-checkbox">
|
62 |
+
<input type="checkbox" name="_members_only" id="_members_only" ' . checked( get_post_meta( $thepostid, '_members_only', true ), 'yes', false ) . ' />
|
63 |
+
<label for="_members_only">' . __( 'Members only', 'download_monitor' ) . '</label>
|
64 |
+
<span class="description">' . __( 'Only logged in users will be able to access the file via a download link if this is enabled.', 'download_monitor' ) . '</span>
|
65 |
+
</p>';
|
66 |
+
|
67 |
+
do_action( 'dlm_options_end', $thepostid );
|
68 |
+
|
69 |
+
echo '</div>';
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* download_files function.
|
74 |
+
*
|
75 |
+
* @access public
|
76 |
+
* @return void
|
77 |
+
*/
|
78 |
+
public function download_files() {
|
79 |
+
global $post, $download_monitor;
|
80 |
+
|
81 |
+
wp_nonce_field( 'save_meta_data', 'dlm_nonce' );
|
82 |
+
?>
|
83 |
+
<div class="download_monitor_files dlm-metaboxes-wrapper">
|
84 |
+
|
85 |
+
<p class="toolbar">
|
86 |
+
<a href="#" class="button plus add_file"><?php _e('Add version', 'download_monitor'); ?></a>
|
87 |
+
<a href="#" class="close_all"><?php _e('Close all', 'download_monitor'); ?></a><a href="#" class="expand_all"><?php _e('Expand all', 'download_monitor'); ?></a>
|
88 |
+
</p>
|
89 |
+
|
90 |
+
<div class="dlm-metaboxes downloadable_files">
|
91 |
+
<?php
|
92 |
+
$i = -1;
|
93 |
+
$files = get_posts( 'post_parent=' . $post->ID . '&post_type=dlm_download_version&orderby=menu_order&order=ASC&post_status=any&numberposts=-1' );
|
94 |
+
|
95 |
+
if ( $files ) foreach ( $files as $file ) {
|
96 |
+
|
97 |
+
$i++;
|
98 |
+
$file_id = $file->ID;
|
99 |
+
$file_version = ( $file_version = get_post_meta( $file->ID, '_version', true ) ) ? $file_version : '';
|
100 |
+
$file_post_date = $file->post_date;
|
101 |
+
$file_download_count = absint( get_post_meta( $file->ID, '_download_count', true ) );
|
102 |
+
$file_urls = array_filter( (array) get_post_meta( $file->ID, '_files', true ) );
|
103 |
+
|
104 |
+
include( 'html-downloadable-file-version.php' );
|
105 |
+
}
|
106 |
+
?>
|
107 |
+
</div>
|
108 |
+
|
109 |
+
</div>
|
110 |
+
<?php
|
111 |
+
ob_start();
|
112 |
+
?>
|
113 |
+
jQuery(function(){
|
114 |
+
|
115 |
+
// Expand all files
|
116 |
+
jQuery('.expand_all').click(function(){
|
117 |
+
jQuery(this).closest('.dlm-metaboxes-wrapper').find('.dlm-metabox table').show();
|
118 |
+
return false;
|
119 |
+
});
|
120 |
+
|
121 |
+
// Close all files
|
122 |
+
jQuery('.close_all').click(function(){
|
123 |
+
jQuery(this).closest('.dlm-metaboxes-wrapper').find('.dlm-metabox table').hide();
|
124 |
+
return false;
|
125 |
+
});
|
126 |
+
|
127 |
+
// Open/close
|
128 |
+
jQuery('.dlm-metaboxes-wrapper').on('click', '.dlm-metabox h3', function(event){
|
129 |
+
// If the user clicks on some form input inside the h3, like a select list (for variations), the box should not be toggled
|
130 |
+
if (jQuery(event.target).filter(':input, option').length) return;
|
131 |
+
|
132 |
+
jQuery(this).next('.dlm-metabox-content').toggle();
|
133 |
+
});
|
134 |
+
|
135 |
+
// Closes all to begin
|
136 |
+
jQuery('.dlm-metabox.closed').each(function(){
|
137 |
+
jQuery(this).find('.dlm-metabox-content').hide();
|
138 |
+
});
|
139 |
+
|
140 |
+
// Date picker
|
141 |
+
jQuery( ".date-picker-field" ).datepicker({
|
142 |
+
dateFormat: "yy-mm-dd",
|
143 |
+
numberOfMonths: 1,
|
144 |
+
showButtonPanel: true,
|
145 |
+
});
|
146 |
+
|
147 |
+
// Ordering
|
148 |
+
jQuery('.downloadable_files').sortable({
|
149 |
+
items:'.downloadable_file',
|
150 |
+
cursor:'move',
|
151 |
+
axis:'y',
|
152 |
+
handle: 'h3',
|
153 |
+
scrollSensitivity:40,
|
154 |
+
forcePlaceholderSize: true,
|
155 |
+
helper: 'clone',
|
156 |
+
opacity: 0.65,
|
157 |
+
placeholder: 'dlm-metabox-sortable-placeholder',
|
158 |
+
start:function(event,ui){
|
159 |
+
ui.item.css('background-color','#f6f6f6');
|
160 |
+
},
|
161 |
+
stop:function(event,ui){
|
162 |
+
ui.item.removeAttr('style');
|
163 |
+
downloadable_file_row_indexes();
|
164 |
+
}
|
165 |
+
});
|
166 |
+
|
167 |
+
function downloadable_file_row_indexes() {
|
168 |
+
jQuery('.downloadable_files .downloadable_file').each(function(index, el){
|
169 |
+
jQuery('.file_menu_order', el).val( parseInt( jQuery(el).index('.downloadable_files .downloadable_file') ) );
|
170 |
+
});
|
171 |
+
};
|
172 |
+
|
173 |
+
// Add a file
|
174 |
+
jQuery('.download_monitor_files').on('click', 'a.add_file', function(){
|
175 |
+
|
176 |
+
jQuery('.download_monitor_files').block({ message: null, overlayCSS: { background: '#fff url(<?php echo $download_monitor->plugin_url(); ?>/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
|
177 |
+
|
178 |
+
var size = jQuery('.downloadable_files .downloadable_file').size();
|
179 |
+
|
180 |
+
var data = {
|
181 |
+
action: 'download_monitor_add_file',
|
182 |
+
post_id: <?php echo $post->ID; ?>,
|
183 |
+
size: size,
|
184 |
+
security: '<?php echo wp_create_nonce("add-file"); ?>'
|
185 |
+
};
|
186 |
+
|
187 |
+
jQuery.post('<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) {
|
188 |
+
|
189 |
+
jQuery('.downloadable_files').prepend( response );
|
190 |
+
|
191 |
+
downloadable_file_row_indexes();
|
192 |
+
|
193 |
+
jQuery('.download_monitor_files').unblock();
|
194 |
+
|
195 |
+
// Date picker
|
196 |
+
jQuery( ".date-picker-field" ).datepicker({
|
197 |
+
dateFormat: "yy-mm-dd",
|
198 |
+
numberOfMonths: 1,
|
199 |
+
showButtonPanel: true,
|
200 |
+
});
|
201 |
+
});
|
202 |
+
|
203 |
+
return false;
|
204 |
+
|
205 |
+
});
|
206 |
+
|
207 |
+
// Remove a file
|
208 |
+
jQuery('.download_monitor_files').on('click', 'button.remove_file', function(e){
|
209 |
+
e.preventDefault();
|
210 |
+
var answer = confirm('<?php _e( 'Are you sure you want to delete this file?', 'download_monitor' ); ?>');
|
211 |
+
if ( answer ) {
|
212 |
+
|
213 |
+
var el = jQuery(this).closest('.downloadable_file');
|
214 |
+
var file_id = el.attr('data-file');
|
215 |
+
|
216 |
+
if ( file_id > 0 ) {
|
217 |
+
|
218 |
+
jQuery(el).block({ message: null, overlayCSS: { background: '#fff url(<?php echo $download_monitor->plugin_url(); ?>/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
|
219 |
+
|
220 |
+
var data = {
|
221 |
+
action: 'download_monitor_remove_file',
|
222 |
+
file_id: file_id,
|
223 |
+
download_id: '<?php echo $post->ID; ?>',
|
224 |
+
security: '<?php echo wp_create_nonce( "remove-file" ); ?>'
|
225 |
+
};
|
226 |
+
|
227 |
+
jQuery.post('<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) {
|
228 |
+
jQuery(el).fadeOut('300').remove();
|
229 |
+
});
|
230 |
+
|
231 |
+
} else {
|
232 |
+
jQuery(el).fadeOut('300').remove();
|
233 |
+
}
|
234 |
+
}
|
235 |
+
return false;
|
236 |
+
});
|
237 |
+
|
238 |
+
// Browse for file
|
239 |
+
jQuery('.download_monitor_files').on('click', 'a.browse_for_file', function(e){
|
240 |
+
|
241 |
+
downloadable_files_field = jQuery(this).closest('.downloadable_file').find('textarea[name^="downloadable_file_urls"]');
|
242 |
+
|
243 |
+
window.send_to_editor = window.send_to_browse_file_url;
|
244 |
+
|
245 |
+
tb_show('<?php esc_attr_e( 'Browse for a file', 'download_monitor' ); ?>', 'media-upload.php?post_id=<?php echo $post->ID; ?>&type=downloadable_file_browser&from=wpdlm01&TB_iframe=true');
|
246 |
+
|
247 |
+
return false;
|
248 |
+
});
|
249 |
+
|
250 |
+
window.send_to_browse_file_url = function(html) {
|
251 |
+
|
252 |
+
if ( html ) {
|
253 |
+
old = jQuery.trim( jQuery(downloadable_files_field).val() );
|
254 |
+
if ( old ) old = old + "\n";
|
255 |
+
jQuery(downloadable_files_field).val( old + html );
|
256 |
+
}
|
257 |
+
|
258 |
+
tb_remove();
|
259 |
+
|
260 |
+
window.send_to_editor = window.send_to_editor_default;
|
261 |
+
}
|
262 |
+
|
263 |
+
// Uploading files
|
264 |
+
var dlm_upload_file_frame;
|
265 |
+
|
266 |
+
jQuery(document).on( 'click', '.dlm_upload_file', function( event ){
|
267 |
+
|
268 |
+
var $el = $(this);
|
269 |
+
var $file_path_field = $el.parent().parent().find('.downloadable_file_urls');
|
270 |
+
var file_paths = $file_path_field.val();
|
271 |
+
|
272 |
+
event.preventDefault();
|
273 |
+
|
274 |
+
// If the media frame already exists, reopen it.
|
275 |
+
if ( dlm_upload_file_frame ) {
|
276 |
+
dlm_upload_file_frame.open();
|
277 |
+
return;
|
278 |
+
}
|
279 |
+
|
280 |
+
var downloadable_file_states = [
|
281 |
+
// Main states.
|
282 |
+
new wp.media.controller.Library({
|
283 |
+
library: wp.media.query(),
|
284 |
+
multiple: true,
|
285 |
+
title: $el.data('choose'),
|
286 |
+
priority: 20,
|
287 |
+
filterable: 'uploaded',
|
288 |
+
})
|
289 |
+
];
|
290 |
+
|
291 |
+
// Create the media frame.
|
292 |
+
dlm_upload_file_frame = wp.media.frames.downloadable_file = wp.media({
|
293 |
+
// Set the title of the modal.
|
294 |
+
title: $el.data('choose'),
|
295 |
+
library: {
|
296 |
+
type: ''
|
297 |
+
},
|
298 |
+
button: {
|
299 |
+
text: $el.data('update'),
|
300 |
+
},
|
301 |
+
multiple: true,
|
302 |
+
states: downloadable_file_states,
|
303 |
+
});
|
304 |
+
|
305 |
+
// When an image is selected, run a callback.
|
306 |
+
dlm_upload_file_frame.on( 'select', function() {
|
307 |
+
|
308 |
+
var selection = dlm_upload_file_frame.state().get('selection');
|
309 |
+
|
310 |
+
selection.map( function( attachment ) {
|
311 |
+
|
312 |
+
attachment = attachment.toJSON();
|
313 |
+
|
314 |
+
if ( attachment.url )
|
315 |
+
file_paths = file_paths ? file_paths + "\n" + attachment.url : attachment.url
|
316 |
+
|
317 |
+
} );
|
318 |
+
|
319 |
+
$file_path_field.val( file_paths );
|
320 |
+
});
|
321 |
+
|
322 |
+
// Set post to 0 and set our custom type
|
323 |
+
dlm_upload_file_frame.on( 'ready', function() {
|
324 |
+
dlm_upload_file_frame.uploader.options.uploader.params = {
|
325 |
+
type: 'dlm_download'
|
326 |
+
};
|
327 |
+
});
|
328 |
+
|
329 |
+
// Finally, open the modal.
|
330 |
+
dlm_upload_file_frame.open();
|
331 |
+
});
|
332 |
+
|
333 |
+
});
|
334 |
+
<?php
|
335 |
+
$js_code = ob_get_clean();
|
336 |
+
$download_monitor->add_inline_js( $js_code );
|
337 |
+
}
|
338 |
+
|
339 |
+
/**
|
340 |
+
* short_description function.
|
341 |
+
*
|
342 |
+
* @access public
|
343 |
+
* @param mixed $post
|
344 |
+
* @return void
|
345 |
+
*/
|
346 |
+
public function short_description( $post ) {
|
347 |
+
$settings = array(
|
348 |
+
'quicktags' => array( 'buttons' => 'em,strong,link' ),
|
349 |
+
'textarea_name' => 'excerpt',
|
350 |
+
'quicktags' => true,
|
351 |
+
'tinymce' => true,
|
352 |
+
'editor_css' => '<style>#wp-excerpt-editor-container .wp-editor-area{height:200px; width:100%;}</style>'
|
353 |
+
);
|
354 |
+
|
355 |
+
wp_editor( htmlspecialchars_decode( $post->post_excerpt ), 'excerpt', $settings );
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* save_post function.
|
360 |
+
*
|
361 |
+
* @access public
|
362 |
+
* @param mixed $post_id
|
363 |
+
* @param mixed $post
|
364 |
+
* @return void
|
365 |
+
*/
|
366 |
+
public function save_post( $post_id, $post ) {
|
367 |
+
if ( empty( $post_id ) || empty( $post ) || empty( $_POST ) ) return;
|
368 |
+
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return;
|
369 |
+
if ( is_int( wp_is_post_revision( $post ) ) ) return;
|
370 |
+
if ( is_int( wp_is_post_autosave( $post ) ) ) return;
|
371 |
+
if ( empty($_POST['dlm_nonce']) || ! wp_verify_nonce( $_POST['dlm_nonce'], 'save_meta_data' ) ) return;
|
372 |
+
if ( ! current_user_can( 'edit_post', $post_id ) ) return;
|
373 |
+
if ( $post->post_type != 'dlm_download' ) return;
|
374 |
+
|
375 |
+
do_action( 'dlm_save_meta_boxes', $post_id, $post );
|
376 |
+
}
|
377 |
+
|
378 |
+
/**
|
379 |
+
* save function.
|
380 |
+
*
|
381 |
+
* @access public
|
382 |
+
* @param mixed $post_id
|
383 |
+
* @param mixed $post
|
384 |
+
* @return void
|
385 |
+
*/
|
386 |
+
public function save_meta_boxes( $post_id, $post ) {
|
387 |
+
global $wpdb, $download_monitor;
|
388 |
+
|
389 |
+
// Update options
|
390 |
+
$_featured = ( isset( $_POST['_featured'] ) ) ? 'yes' : 'no';
|
391 |
+
$_members_only = ( isset( $_POST['_members_only'] ) ) ? 'yes' : 'no';
|
392 |
+
|
393 |
+
update_post_meta( $post_id, '_featured', $_featured );
|
394 |
+
update_post_meta( $post_id, '_members_only', $_members_only );
|
395 |
+
|
396 |
+
$total_download_count = 0;
|
397 |
+
|
398 |
+
// Process files
|
399 |
+
if ( isset( $_POST['downloadable_file_id'] ) ) {
|
400 |
+
|
401 |
+
$downloadable_file_id = $_POST['downloadable_file_id'];
|
402 |
+
$downloadable_file_menu_order = $_POST['downloadable_file_menu_order'];
|
403 |
+
$downloadable_file_version = $_POST['downloadable_file_version'];
|
404 |
+
$downloadable_file_urls = $_POST['downloadable_file_urls'];
|
405 |
+
$downloadable_file_date = $_POST['downloadable_file_date'];
|
406 |
+
$downloadable_file_date_hour = $_POST['downloadable_file_date_hour'];
|
407 |
+
$downloadable_file_date_minute = $_POST['downloadable_file_date_minute'];
|
408 |
+
$downloadable_file_download_count = $_POST['downloadable_file_download_count'];
|
409 |
+
|
410 |
+
for ( $i = 0; $i <= max( array_keys( $downloadable_file_id ) ); $i ++ ) {
|
411 |
+
|
412 |
+
if ( ! isset( $downloadable_file_id[ $i ] ) )
|
413 |
+
continue;
|
414 |
+
|
415 |
+
$file_id = absint( $downloadable_file_id[ $i ] );
|
416 |
+
$file_menu_order = absint( $downloadable_file_menu_order[ $i ] );
|
417 |
+
$file_version = sanitize_text_field( $downloadable_file_version[ $i ] );
|
418 |
+
$file_date_hour = absint( $downloadable_file_date_hour[ $i ] );
|
419 |
+
$file_date_minute = absint( $downloadable_file_date_minute[ $i ] );
|
420 |
+
$file_date = sanitize_text_field( $downloadable_file_date[ $i ] );
|
421 |
+
$file_download_count = sanitize_text_field( $downloadable_file_download_count[ $i ] );
|
422 |
+
$files = array_filter( array_map( 'trim', explode( "\n", $downloadable_file_urls[ $i ] ) ) );
|
423 |
+
|
424 |
+
if ( ! $file_id )
|
425 |
+
continue;
|
426 |
+
|
427 |
+
// Generate a useful post title
|
428 |
+
$file_post_title = 'Download #' . $post_id . ' File Version';
|
429 |
+
|
430 |
+
// Generate date
|
431 |
+
if ( empty( $file_date ) ) {
|
432 |
+
$date = current_time('timestamp');
|
433 |
+
} else {
|
434 |
+
$date = strtotime( $file_date . ' ' . $file_date_hour . ':' . $file_date_minute . ':00' );
|
435 |
+
}
|
436 |
+
|
437 |
+
// Update
|
438 |
+
$wpdb->update( $wpdb->posts, array(
|
439 |
+
'post_status' => 'publish',
|
440 |
+
'post_title' => $file_post_title,
|
441 |
+
'menu_order' => $file_menu_order,
|
442 |
+
'post_date' => date( 'Y-m-d H:i:s', $date )
|
443 |
+
), array( 'ID' => $file_id ) );
|
444 |
+
|
445 |
+
// Update post meta
|
446 |
+
update_post_meta( $file_id, '_version', $file_version );
|
447 |
+
update_post_meta( $file_id, '_files', $files );
|
448 |
+
|
449 |
+
$filesize = null;
|
450 |
+
$url = current( $files );
|
451 |
+
|
452 |
+
if ( file_exists( $url ) && ( $filesize = filesize( $url ) ) )
|
453 |
+
$filesize = $filesize;
|
454 |
+
else {
|
455 |
+
$file = wp_remote_head( $url );
|
456 |
+
|
457 |
+
if ( ! is_wp_error( $file ) && ! empty( $file['headers']['content-length'] ) )
|
458 |
+
$filesize = $file['headers']['content-length'];
|
459 |
+
}
|
460 |
+
|
461 |
+
update_post_meta( $file_id, '_filesize', $filesize );
|
462 |
+
|
463 |
+
if ( $file_download_count !== '' ) {
|
464 |
+
update_post_meta( $file_id, '_download_count', absint( $file_download_count ) );
|
465 |
+
$total_download_count += absint( $file_download_count );
|
466 |
+
} else {
|
467 |
+
$total_download_count += absint( get_post_meta( $file_id, '_download_count', true ) );
|
468 |
+
}
|
469 |
+
}
|
470 |
+
}
|
471 |
+
|
472 |
+
// Sync download_count
|
473 |
+
update_post_meta( $post_id, '_download_count', $total_download_count );
|
474 |
+
|
475 |
+
// Clear transients
|
476 |
+
delete_transient( 'dlm_children_ids_' . $post_id );
|
477 |
+
}
|
478 |
+
}
|
479 |
+
|
480 |
+
new DLM_Admin_Writepanels();
|
includes/admin/class-dlm-admin.php
ADDED
@@ -0,0 +1,413 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* DLM_Admin class.
|
7 |
+
*/
|
8 |
+
class DLM_Admin {
|
9 |
+
|
10 |
+
private $settings;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* __construct function.
|
14 |
+
*
|
15 |
+
* @access public
|
16 |
+
* @return void
|
17 |
+
*/
|
18 |
+
public function __construct() {
|
19 |
+
include_once( 'class-dlm-admin-writepanels.php' );
|
20 |
+
include_once( 'class-dlm-admin-media-browser.php' );
|
21 |
+
include_once( 'class-dlm-admin-cpt.php' );
|
22 |
+
include_once( 'class-dlm-admin-insert.php' );
|
23 |
+
|
24 |
+
// Directory protection
|
25 |
+
add_filter( 'mod_rewrite_rules', array( $this, 'ms_files_protection' ) );
|
26 |
+
add_filter( 'upload_dir', array( $this, 'upload_dir' ) );
|
27 |
+
|
28 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
29 |
+
add_action( 'admin_menu', array( $this, 'admin_menu' ), 12 );
|
30 |
+
add_action( 'admin_init', array( $this, 'register_settings' ) );
|
31 |
+
add_action( 'admin_init', array( $this, 'export_logs' ) );
|
32 |
+
add_action( 'wp_dashboard_setup', array( $this, 'admin_dashboard' ) );
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* ms_files_protection function.
|
37 |
+
*
|
38 |
+
* @access public
|
39 |
+
* @param mixed $rewrite
|
40 |
+
* @return void
|
41 |
+
*/
|
42 |
+
public function ms_files_protection( $rewrite ) {
|
43 |
+
global $wp_rewrite;
|
44 |
+
|
45 |
+
if ( ! is_multisite() )
|
46 |
+
return $rewrite;
|
47 |
+
|
48 |
+
$rule = "\n# DLM Rules - Protect Files from ms-files.php\n\n";
|
49 |
+
$rule .= "<IfModule mod_rewrite.c>\n";
|
50 |
+
$rule .= "RewriteEngine On\n";
|
51 |
+
$rule .= "RewriteCond %{QUERY_STRING} file=dlm_uploads/ [NC]\n";
|
52 |
+
$rule .= "RewriteRule /ms-files.php$ - [F]\n";
|
53 |
+
$rule .= "</IfModule>\n\n";
|
54 |
+
|
55 |
+
return $rule . $rewrite;
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* upload_dir function.
|
60 |
+
*
|
61 |
+
* @access public
|
62 |
+
* @param mixed $pathdata
|
63 |
+
* @return void
|
64 |
+
*/
|
65 |
+
public function upload_dir( $pathdata ) {
|
66 |
+
|
67 |
+
if ( isset( $_POST['type'] ) && $_POST['type'] == 'dlm_download' ) {
|
68 |
+
$subdir = '/dlm_uploads' . $pathdata['subdir'];
|
69 |
+
$pathdata['path'] = str_replace( $pathdata['subdir'], $subdir, $pathdata['path'] );
|
70 |
+
$pathdata['url'] = str_replace( $pathdata['subdir'], $subdir, $pathdata['url'] );
|
71 |
+
$pathdata['subdir'] = str_replace( $pathdata['subdir'], $subdir, $pathdata['subdir'] );
|
72 |
+
}
|
73 |
+
|
74 |
+
return $pathdata;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* init_settings function.
|
79 |
+
*
|
80 |
+
* @access private
|
81 |
+
* @return void
|
82 |
+
*/
|
83 |
+
private function init_settings() {
|
84 |
+
$this->settings = apply_filters( 'download_monitor_settings',
|
85 |
+
array(
|
86 |
+
'general' => array(
|
87 |
+
__( 'General', 'download_monitor' ),
|
88 |
+
array(
|
89 |
+
array(
|
90 |
+
'name' => 'dlm_default_template',
|
91 |
+
'std' => '',
|
92 |
+
'placeholder' => __( '', 'download_monitor' ),
|
93 |
+
'label' => __( 'Default Template', 'download_monitor' ),
|
94 |
+
'desc' => __( 'Choose which template is used for <code>[download]</code> shortcodes by default (this can be overridden by the <code>format</code> argument).', 'download_monitor' ) . ' ' . __( 'Leaving this blank will use the default <code>content-download.php</code> template file. If you enter, for example, <code>image</code>, the <code>content-download-image.php</code> template will be used instead.', 'download_monitor' )
|
95 |
+
),
|
96 |
+
),
|
97 |
+
),
|
98 |
+
'endpoints' => array(
|
99 |
+
__( 'Endpoint', 'download_monitor' ),
|
100 |
+
array(
|
101 |
+
array(
|
102 |
+
'name' => 'dlm_download_endpoint',
|
103 |
+
'std' => 'download',
|
104 |
+
'placeholder' => __( 'download', 'download_monitor' ),
|
105 |
+
'label' => __( 'Download Endpoint', 'download_monitor' ),
|
106 |
+
'desc' => sprintf( __( 'Define what endpoint should be used for download links. By default this will be <code>%s</code>.', 'download_monitor' ), home_url( '/download/' ) )
|
107 |
+
),
|
108 |
+
array(
|
109 |
+
'name' => 'dlm_download_endpoint_value',
|
110 |
+
'std' => 'ID',
|
111 |
+
'label' => __( 'Endpoint Value', 'download_monitor' ),
|
112 |
+
'desc' => sprintf( __( 'Define what unique value should be used on the end of your endpoint to identify the downloadable file. e.g. ID would give a link like <code>%s</code>', 'download_monitor' ), home_url( '/download/10/' ) ),
|
113 |
+
'type' => 'select',
|
114 |
+
'options' => array(
|
115 |
+
'ID' => __( 'Download ID', 'download_monitor' ),
|
116 |
+
'slug' => __( 'Download slug', 'download_monitor' )
|
117 |
+
)
|
118 |
+
),
|
119 |
+
array(
|
120 |
+
'name' => 'dlm_xsendfile_enabled',
|
121 |
+
'std' => '',
|
122 |
+
'label' => __( 'X-Accel-Redirect / X-Sendfile', 'download_monitor' ),
|
123 |
+
'cb_label' => __( 'Enable', 'download_monitor' ),
|
124 |
+
'desc' => __( 'If supported, <code>X-Accel-Redirect</code> / <code>X-Sendfile</code> can be used to serve downloads instead of PHP (server requires <code>mod_xsendfile</code>).', 'download_monitor' ),
|
125 |
+
'type' => 'checkbox'
|
126 |
+
)
|
127 |
+
)
|
128 |
+
),
|
129 |
+
'logging' => array(
|
130 |
+
__( 'Logging', 'download_monitor' ),
|
131 |
+
array(
|
132 |
+
array(
|
133 |
+
'name' => 'dlm_enable_logging',
|
134 |
+
'cb_label' => __( 'Enable', 'download_monitor' ),
|
135 |
+
'std' => '1',
|
136 |
+
'label' => __( 'Download Log', 'download_monitor' ),
|
137 |
+
'desc' => __( 'Log download attempts, IP addresses and more.', 'download_monitor' ),
|
138 |
+
'type' => 'checkbox'
|
139 |
+
),
|
140 |
+
array(
|
141 |
+
'name' => 'dlm_ip_blacklist',
|
142 |
+
'std' => '192.168.0.*',
|
143 |
+
'label' => __( 'Blacklist IPs', 'download_monitor' ),
|
144 |
+
'desc' => __( 'List IP Addresses to blacklist, 1 per line. Use <code>*</code> for a wildcard.', 'download_monitor' ),
|
145 |
+
'placeholder' => '',
|
146 |
+
'type' => 'textarea'
|
147 |
+
),
|
148 |
+
array(
|
149 |
+
'name' => 'dlm_user_agent_blacklist',
|
150 |
+
'std' => 'Googlebot',
|
151 |
+
'label' => __( 'Blacklist user agents', 'download_monitor' ),
|
152 |
+
'desc' => __( 'List browser user agents to blacklist, 1 per line.', 'download_monitor' ),
|
153 |
+
'placeholder' => '',
|
154 |
+
'type' => 'textarea'
|
155 |
+
),
|
156 |
+
)
|
157 |
+
)
|
158 |
+
)
|
159 |
+
);
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* register_settings function.
|
164 |
+
*
|
165 |
+
* @access public
|
166 |
+
* @return void
|
167 |
+
*/
|
168 |
+
public function register_settings() {
|
169 |
+
$this->init_settings();
|
170 |
+
|
171 |
+
foreach ( $this->settings as $section ) {
|
172 |
+
foreach ( $section[1] as $option ) {
|
173 |
+
if ( isset( $option['std'] ) )
|
174 |
+
add_option( $option['name'], $option['std'] );
|
175 |
+
register_setting( 'download_monitor', $option['name'] );
|
176 |
+
}
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* admin_enqueue_scripts function.
|
182 |
+
*
|
183 |
+
* @access public
|
184 |
+
* @return void
|
185 |
+
*/
|
186 |
+
public function admin_enqueue_scripts() {
|
187 |
+
global $download_monitor;
|
188 |
+
|
189 |
+
wp_enqueue_script( 'jquery-blockui', $download_monitor->plugin_url() . '/assets/js/blockui.min.js', '2.39', array( 'jquery' ) );
|
190 |
+
wp_enqueue_script( 'jquery-ui-sortable' );
|
191 |
+
wp_enqueue_script( 'jquery-ui-datepicker' );
|
192 |
+
wp_enqueue_style( 'jquery-ui-style', (is_ssl()) ? 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css' : 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css' );
|
193 |
+
wp_enqueue_style( 'download_monitor_admin_css', $download_monitor->plugin_url() . '/assets/css/admin.css' );
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* admin_menu function.
|
198 |
+
*
|
199 |
+
* @access public
|
200 |
+
* @return void
|
201 |
+
*/
|
202 |
+
public function admin_menu() {
|
203 |
+
if ( get_option( 'dlm_enable_logging' ) == 1 )
|
204 |
+
add_submenu_page( 'edit.php?post_type=dlm_download', __( 'Logs', 'download_monitor' ), __( 'Logs', 'download_monitor' ), 'manage_options', 'download-monitor-logs', array( $this, 'log_viewer' ) );
|
205 |
+
|
206 |
+
add_submenu_page( 'edit.php?post_type=dlm_download', __( 'Settings', 'download_monitor' ), __( 'Settings', 'download_monitor' ), 'manage_options', 'download-monitor-settings', array( $this, 'settings_page' ) );
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* settings_page function.
|
211 |
+
*
|
212 |
+
* @access public
|
213 |
+
* @return void
|
214 |
+
*/
|
215 |
+
public function settings_page() {
|
216 |
+
global $download_monitor;
|
217 |
+
|
218 |
+
$this->init_settings();
|
219 |
+
?>
|
220 |
+
<div class="wrap">
|
221 |
+
<form method="post" action="options.php">
|
222 |
+
|
223 |
+
<?php settings_fields( 'download_monitor' ); ?>
|
224 |
+
<?php screen_icon(); ?>
|
225 |
+
|
226 |
+
<h2 class="nav-tab-wrapper">
|
227 |
+
<?php
|
228 |
+
foreach ( $this->settings as $section ) {
|
229 |
+
echo '<a href="#settings-' . sanitize_title( $section[0] ) . '" class="nav-tab">' . esc_html( $section[0] ) . '</a>';
|
230 |
+
}
|
231 |
+
?>
|
232 |
+
</h2><br/>
|
233 |
+
|
234 |
+
<?php
|
235 |
+
if ( ! empty( $_GET['settings-updated'] ) ) {
|
236 |
+
flush_rewrite_rules();
|
237 |
+
echo '<div class="updated fade"><p>' . __( 'Settings successfully saved', 'download_monitor' ) . '</p></div>';
|
238 |
+
}
|
239 |
+
|
240 |
+
foreach ( $this->settings as $section ) {
|
241 |
+
|
242 |
+
echo '<div id="settings-' . sanitize_title( $section[0] ) . '" class="settings_panel">';
|
243 |
+
|
244 |
+
echo '<table class="form-table">';
|
245 |
+
|
246 |
+
foreach ( $section[1] as $option ) {
|
247 |
+
|
248 |
+
$placeholder = ( ! empty( $option['placeholder'] ) ) ? 'placeholder="' . $option['placeholder'] . '"' : '';
|
249 |
+
|
250 |
+
echo '<tr valign="top"><th scope="row"><label for="setting-' . $option['name'] . '">' . $option['label'] . '</a></th><td>';
|
251 |
+
|
252 |
+
if ( ! isset( $option['type'] ) ) $option['type'] = '';
|
253 |
+
|
254 |
+
$value = get_option( $option['name'] );
|
255 |
+
|
256 |
+
switch ( $option['type'] ) {
|
257 |
+
|
258 |
+
case "checkbox" :
|
259 |
+
|
260 |
+
?><label><input id="setting-<?php echo $option['name']; ?>" name="<?php echo $option['name']; ?>" type="checkbox" value="1" <?php checked( '1', $value ); ?> /> <?php echo $option['cb_label']; ?></label><?php
|
261 |
+
|
262 |
+
if ( $option['desc'] )
|
263 |
+
echo ' <p class="description">' . $option['desc'] . '</p>';
|
264 |
+
|
265 |
+
break;
|
266 |
+
case "textarea" :
|
267 |
+
|
268 |
+
?><textarea id="setting-<?php echo $option['name']; ?>" class="large-text" cols="50" rows="3" name="<?php echo $option['name']; ?>" <?php echo $placeholder; ?>><?php echo esc_textarea( $value ); ?></textarea><?php
|
269 |
+
|
270 |
+
if ( $option['desc'] )
|
271 |
+
echo ' <p class="description">' . $option['desc'] . '</p>';
|
272 |
+
|
273 |
+
break;
|
274 |
+
case "select" :
|
275 |
+
|
276 |
+
?><select id="setting-<?php echo $option['name']; ?>" class="regular-text" name="<?php echo $option['name']; ?>"><?php
|
277 |
+
foreach( $option['options'] as $key => $name )
|
278 |
+
echo '<option value="' . esc_attr( $key ) . '" ' . selected( $value, $key, false ) . '>' . esc_html( $name ) . '</option>';
|
279 |
+
?></select><?php
|
280 |
+
|
281 |
+
if ( $option['desc'] )
|
282 |
+
echo ' <p class="description">' . $option['desc'] . '</p>';
|
283 |
+
|
284 |
+
break;
|
285 |
+
default :
|
286 |
+
|
287 |
+
?><input id="setting-<?php echo $option['name']; ?>" class="regular-text" type="text" name="<?php echo $option['name']; ?>" value="<?php esc_attr_e( $value ); ?>" <?php echo $placeholder; ?> /><?php
|
288 |
+
|
289 |
+
if ( $option['desc'] )
|
290 |
+
echo ' <p class="description">' . $option['desc'] . '</p>';
|
291 |
+
|
292 |
+
break;
|
293 |
+
|
294 |
+
}
|
295 |
+
|
296 |
+
echo '</td></tr>';
|
297 |
+
}
|
298 |
+
|
299 |
+
echo '</table></div>';
|
300 |
+
|
301 |
+
}
|
302 |
+
?>
|
303 |
+
<p class="submit">
|
304 |
+
<input type="submit" class="button-primary" value="<?php _e( 'Save Changes', 'download_monitor' ); ?>" />
|
305 |
+
</p>
|
306 |
+
</form>
|
307 |
+
</div>
|
308 |
+
<?php
|
309 |
+
|
310 |
+
$download_monitor->add_inline_js("
|
311 |
+
jQuery('.nav-tab-wrapper a').click(function() {
|
312 |
+
jQuery('.settings_panel').hide();
|
313 |
+
jQuery('.nav-tab-active').removeClass('nav-tab-active');
|
314 |
+
jQuery( jQuery(this).attr('href') ).show();
|
315 |
+
jQuery(this).addClass('nav-tab-active');
|
316 |
+
return false;
|
317 |
+
});
|
318 |
+
|
319 |
+
jQuery('.nav-tab-wrapper a:first').click();
|
320 |
+
");
|
321 |
+
}
|
322 |
+
|
323 |
+
/**
|
324 |
+
* log_viewer function.
|
325 |
+
*
|
326 |
+
* @access public
|
327 |
+
* @return void
|
328 |
+
*/
|
329 |
+
function log_viewer() {
|
330 |
+
if ( ! class_exists( 'WP_List_Table' ) )
|
331 |
+
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
|
332 |
+
|
333 |
+
require_once( 'class-dlm-logging-list-table.php' );
|
334 |
+
|
335 |
+
$DLM_Logging_List_Table = new DLM_Logging_List_Table();
|
336 |
+
$DLM_Logging_List_Table->prepare_items();
|
337 |
+
?>
|
338 |
+
<div class="wrap">
|
339 |
+
<div id="icon-edit" class="icon32 icon32-posts-dlm_download"><br/></div>
|
340 |
+
|
341 |
+
<h2><?php _e( 'Download Logs', 'download_monitor' ); ?> <a href="<?php echo admin_url( '?dlm_download_logs=true' ); ?>" class="add-new-h2"><?php _e( 'Export CSV', 'download_monitor' ); ?></a></h2><br/>
|
342 |
+
<form id="dlm_logs">
|
343 |
+
<?php $DLM_Logging_List_Table->display() ?>
|
344 |
+
</form>
|
345 |
+
</div>
|
346 |
+
<?php
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* export_logs function.
|
351 |
+
*
|
352 |
+
* @access public
|
353 |
+
* @return void
|
354 |
+
*/
|
355 |
+
public function export_logs() {
|
356 |
+
global $wpdb;
|
357 |
+
|
358 |
+
if ( empty( $_GET['dlm_download_logs'] ) )
|
359 |
+
return;
|
360 |
+
|
361 |
+
$items = $wpdb->get_results(
|
362 |
+
"SELECT * FROM {$wpdb->download_log}
|
363 |
+
WHERE type = 'download'
|
364 |
+
ORDER BY download_date DESC"
|
365 |
+
);
|
366 |
+
|
367 |
+
$rows = array();
|
368 |
+
$row = array();
|
369 |
+
$row[] = __( 'Download ID', 'download_monitor' );
|
370 |
+
$row[] = __( 'Version ID', 'download_monitor' );
|
371 |
+
$row[] = __( 'User ID', 'download_monitor' );
|
372 |
+
$row[] = __( 'User IP', 'download_monitor' );
|
373 |
+
$row[] = __( 'User Agent', 'download_monitor' );
|
374 |
+
$row[] = __( 'Date', 'download_monitor' );
|
375 |
+
$row[] = __( 'Status', 'download_monitor' );
|
376 |
+
$rows[] = '"' . implode( '","', $row ) . '"';
|
377 |
+
|
378 |
+
if ( ! empty( $items ) ) {
|
379 |
+
foreach ( $items as $item ) {
|
380 |
+
$row = array();
|
381 |
+
$row[] = $item->download_id;
|
382 |
+
$row[] = $item->version_id;
|
383 |
+
$row[] = $item->user_id;
|
384 |
+
$row[] = $item->user_ip;
|
385 |
+
$row[] = $item->user_agent;
|
386 |
+
$row[] = $item->download_date;
|
387 |
+
$row[] = $item->download_status . ( $item->download_status_message ? ' - ' : '' ) . $item->download_status_message;
|
388 |
+
$rows[] = '"' . implode( '","', $row ) . '"';
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
$log = implode( "\n", $rows );
|
393 |
+
|
394 |
+
header( "Content-type: text/csv" );
|
395 |
+
header( "Content-Disposition: attachment; filename=download_log.csv" );
|
396 |
+
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
|
397 |
+
header( "Content-Length: " . strlen( $log ) );
|
398 |
+
echo $log;
|
399 |
+
exit;
|
400 |
+
}
|
401 |
+
|
402 |
+
/**
|
403 |
+
* admin_dashboard function.
|
404 |
+
*
|
405 |
+
* @access public
|
406 |
+
* @return void
|
407 |
+
*/
|
408 |
+
public function admin_dashboard() {
|
409 |
+
include_once( 'class-dlm-admin-dashboard.php' );
|
410 |
+
}
|
411 |
+
}
|
412 |
+
|
413 |
+
new DLM_Admin();
|
includes/admin/class-dlm-category-walker.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
3 |
+
|
4 |
+
/**
|
5 |
+
* DLM_Category_Walker class.
|
6 |
+
*
|
7 |
+
* @extends Walker
|
8 |
+
*/
|
9 |
+
class DLM_Category_Walker extends Walker {
|
10 |
+
|
11 |
+
var $tree_type = 'category';
|
12 |
+
var $db_fields = array ('parent' => 'parent', 'id' => 'term_id', 'slug' => 'slug' );
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @see Walker::start_el()
|
16 |
+
* @since 2.1.0
|
17 |
+
*
|
18 |
+
* @param string $output Passed by reference. Used to append additional content.
|
19 |
+
* @param object $category Category data object.
|
20 |
+
* @param int $depth Depth of category in reference to parents.
|
21 |
+
* @param array $args
|
22 |
+
*/
|
23 |
+
function start_el( $output, $cat, $depth, $args ) {
|
24 |
+
|
25 |
+
if ( ! empty( $args['hierarchical'] ) )
|
26 |
+
$pad = str_repeat(' ', $depth * 3);
|
27 |
+
else
|
28 |
+
$pad = '';
|
29 |
+
|
30 |
+
$cat_name = apply_filters( 'list_product_cats', $cat->name, $cat );
|
31 |
+
|
32 |
+
$value = isset( $args['value'] ) && $args['value'] == 'id' ? $cat->term_id : $cat->slug;
|
33 |
+
|
34 |
+
$output .= "\t<option class=\"level-$depth\" value=\"" . $value . "\"";
|
35 |
+
|
36 |
+
if ( $value == $args['selected'] || ( is_array( $args['selected'] ) && in_array( $value, $args['selected'] ) ) )
|
37 |
+
$output .= ' selected="selected"';
|
38 |
+
|
39 |
+
$output .= '>';
|
40 |
+
|
41 |
+
$output .= $pad . __( $cat_name, 'download_monitor' );
|
42 |
+
|
43 |
+
if ( ! empty( $args['show_count'] ) )
|
44 |
+
$output .= ' (' . $cat->count . ')';
|
45 |
+
|
46 |
+
$output .= "</option>\n";
|
47 |
+
}
|
48 |
+
}
|
includes/admin/class-dlm-logging-list-table.php
ADDED
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* DLM_Logging_List_Table class.
|
4 |
+
*
|
5 |
+
* @extends WP_List_Table
|
6 |
+
*/
|
7 |
+
class DLM_Logging_List_Table extends WP_List_Table {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* __construct function.
|
11 |
+
*
|
12 |
+
* @access public
|
13 |
+
*/
|
14 |
+
function __construct(){
|
15 |
+
global $status, $page;
|
16 |
+
|
17 |
+
parent::__construct( array(
|
18 |
+
'singular' => 'log',
|
19 |
+
'plural' => 'logs',
|
20 |
+
'ajax' => false
|
21 |
+
) );
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* column_default function.
|
26 |
+
*
|
27 |
+
* @access public
|
28 |
+
* @param mixed $log
|
29 |
+
* @param mixed $column_name
|
30 |
+
* @return void
|
31 |
+
*/
|
32 |
+
function column_default( $log, $column_name ) {
|
33 |
+
switch( $column_name ) {
|
34 |
+
case 'status' :
|
35 |
+
switch ( $log->download_status ) {
|
36 |
+
case 'failed' :
|
37 |
+
$download_status = '<span class="failed" title="' . esc_attr( $log->download_status_message ) . '">❢</span>';
|
38 |
+
break;
|
39 |
+
case 'redirected' :
|
40 |
+
$download_status = '<span class="redirected" title="' . esc_attr( $log->download_status_message ) . '">➜</span>';
|
41 |
+
break;
|
42 |
+
default :
|
43 |
+
$download_status = '<span class="completed" title="' . __( 'Download Complete', 'download_monitor' ) . '">✔</span>';
|
44 |
+
break;
|
45 |
+
}
|
46 |
+
|
47 |
+
return $download_status;
|
48 |
+
break;
|
49 |
+
case 'date' :
|
50 |
+
return '<time title="' . date_i18n( get_option( 'date_format' ) . ' @ ' . get_option( 'time_format' ), strtotime( $log->download_date ) ) . '"">' . sprintf( __( '%s ago', 'download_monitor' ), human_time_diff( strtotime( $log->download_date ) ) ) . '</time>';
|
51 |
+
break;
|
52 |
+
case 'download' :
|
53 |
+
$download = new DLM_Download( $log->download_id );
|
54 |
+
$download->set_version( $log->version_id );
|
55 |
+
|
56 |
+
if ( ! $download->exists() ) {
|
57 |
+
$download_string = sprintf( __( 'Download #%d (no longer exists)', 'download_monitor' ), $log->download_id );
|
58 |
+
} else {
|
59 |
+
$download_string = '<a href="' . admin_url( 'post.php?post=' . $download->id . '&action=edit' ) . '">';
|
60 |
+
$download_string .= '#' . $download->id . ' – ' . $download->get_the_title();
|
61 |
+
$download_string .= '</a>';
|
62 |
+
}
|
63 |
+
|
64 |
+
if ( $log->version )
|
65 |
+
$download_string .= ' (' . sprintf( __( 'v%s', 'download_monitor' ), $log->version ) . ')';
|
66 |
+
|
67 |
+
return $download_string;
|
68 |
+
break;
|
69 |
+
case 'file' :
|
70 |
+
$download = new DLM_Download( $log->download_id );
|
71 |
+
$download->set_version( $log->version_id );
|
72 |
+
|
73 |
+
if ( $download->exists() && $download->get_the_filename() )
|
74 |
+
$download_string = '<code>' . $download->get_the_filename() . '</code>';
|
75 |
+
else
|
76 |
+
$download_string = '–';
|
77 |
+
|
78 |
+
return $download_string;
|
79 |
+
break;
|
80 |
+
case 'user' :
|
81 |
+
if ( $log->user_id )
|
82 |
+
$user = get_user_by( 'id', $log->user_id );
|
83 |
+
|
84 |
+
if ( ! isset( $user ) || ! $user ) {
|
85 |
+
$user_string = __( 'Non-member', 'download_monitor' );
|
86 |
+
} else {
|
87 |
+
$user_string = '<a href="' . admin_url( 'user-edit.php?user_id=' . $user->ID ) . '">';
|
88 |
+
$user_string .= $user->user_login . ' – ';
|
89 |
+
$user_string .= '<a href="mailto:' . $user->user_email . '">';
|
90 |
+
$user_string .= $user->user_email;
|
91 |
+
$user_string .= '</a>';
|
92 |
+
}
|
93 |
+
|
94 |
+
return $user_string;
|
95 |
+
break;
|
96 |
+
case 'user_ip' :
|
97 |
+
return '<a href="http://whois.arin.net/rest/net/NET-' . $log->user_ip . '" target="_blank">' . $log->user_ip . '</a>';
|
98 |
+
break;
|
99 |
+
case 'user_ua' :
|
100 |
+
$ua = $this->uaparser->parse( $log->user_agent );
|
101 |
+
|
102 |
+
return $ua->toFullString;
|
103 |
+
break;
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* get_columns function.
|
109 |
+
*
|
110 |
+
* @access public
|
111 |
+
* @return void
|
112 |
+
*/
|
113 |
+
public function get_columns(){
|
114 |
+
$columns = array(
|
115 |
+
'status' => '',
|
116 |
+
'download' => __( 'Download', 'download_monitor' ),
|
117 |
+
'file' => __( 'File', 'download_monitor' ),
|
118 |
+
'user' => __( 'User', 'download_monitor' ),
|
119 |
+
'user_ip' => __( 'IP Address', 'download_monitor' ),
|
120 |
+
'user_ua' => __( 'User Agent', 'download_monitor' ),
|
121 |
+
'date' => __( 'Date', 'download_monitor' ),
|
122 |
+
);
|
123 |
+
return $columns;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* prepare_items function.
|
128 |
+
*
|
129 |
+
* @access public
|
130 |
+
* @return void
|
131 |
+
*/
|
132 |
+
function prepare_items() {
|
133 |
+
global $wpdb;
|
134 |
+
|
135 |
+
$per_page = 40;
|
136 |
+
$current_page = $this->get_pagenum();
|
137 |
+
|
138 |
+
// Init headers
|
139 |
+
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
|
140 |
+
|
141 |
+
// Total Count of Logs
|
142 |
+
$total_items = $wpdb->get_var(
|
143 |
+
"SELECT COUNT( ID ) FROM {$wpdb->download_log} WHERE type = 'download'"
|
144 |
+
);
|
145 |
+
|
146 |
+
// Get Logs
|
147 |
+
$this->items = $wpdb->get_results(
|
148 |
+
$wpdb->prepare(
|
149 |
+
"SELECT * FROM {$wpdb->download_log}
|
150 |
+
WHERE type = 'download'
|
151 |
+
ORDER BY download_date DESC
|
152 |
+
LIMIT %d, %d",
|
153 |
+
( $current_page - 1 ) * $per_page,
|
154 |
+
$per_page
|
155 |
+
)
|
156 |
+
);
|
157 |
+
|
158 |
+
// Pagination
|
159 |
+
$this->set_pagination_args( array(
|
160 |
+
'total_items' => $total_items,
|
161 |
+
'per_page' => $per_page,
|
162 |
+
'total_pages' => ceil( $total_items / $per_page )
|
163 |
+
) );
|
164 |
+
|
165 |
+
// Parser
|
166 |
+
if ( ! class_exists( 'UAParser' ) )
|
167 |
+
require_once( "uaparser/uaparser.php" );
|
168 |
+
|
169 |
+
$this->uaparser = new UAParser;
|
170 |
+
}
|
171 |
+
}
|
includes/admin/html-downloadable-file-version.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="dlm-metabox closed downloadable_file" data-file="<?php echo $file_id; ?>">
|
2 |
+
<h3>
|
3 |
+
<button type="button" class="remove_file button"><?php _e( 'Remove', 'download_monitor' ); ?></button>
|
4 |
+
<div class="handlediv" title="<?php _e( 'Click to toggle', 'download_monitor' ); ?>"></div>
|
5 |
+
<strong>#<?php echo $file_id; ?> — <?php echo sprintf( __( 'Version <span class="version">%s</span> (%s)', 'download_monitor' ), ( $file_version ) ? $file_version : __('n/a', 'download_monitor'), date_i18n( get_option( 'date_format' ), strtotime( $file_post_date ) ) ); ?> — <?php echo sprintf( _n('Downloaded %s time', 'Downloaded %s times', $file_download_count, 'download_monitor'), $file_download_count ); ?></strong>
|
6 |
+
<input type="hidden" name="downloadable_file_id[<?php echo $i; ?>]" value="<?php echo $file_id; ?>" />
|
7 |
+
<input type="hidden" class="file_menu_order" name="downloadable_file_menu_order[<?php echo $i; ?>]" value="<?php echo $i; ?>" />
|
8 |
+
</h3>
|
9 |
+
<table cellpadding="0" cellspacing="0" class="dlm-metabox-content">
|
10 |
+
<tbody>
|
11 |
+
<tr>
|
12 |
+
<td width="1%">
|
13 |
+
<label><?php _e( 'Version', 'download_monitor' ); ?>:</label>
|
14 |
+
<input type="text" class="short" name="downloadable_file_version[<?php echo $i; ?>]" placeholder="<?php _e( 'n/a', 'download_monitor' ); ?>" value="<?php echo $file_version; ?>" />
|
15 |
+
</td>
|
16 |
+
<td rowspan="3">
|
17 |
+
|
18 |
+
<label><?php _e( 'File URL(s)', 'download_monitor' ); ?>:</label>
|
19 |
+
<textarea name="downloadable_file_urls[<?php echo $i; ?>]" wrap="off" class="downloadable_file_urls" cols="5" rows="5" placeholder="<?php _e( 'Enter one file path/URL per line - multiple files will be used as mirrors (chosen at random).', 'download_monitor' ); ?>"><?php echo esc_textarea( implode( "\n", $file_urls ) ); ?></textarea>
|
20 |
+
<p>
|
21 |
+
<a href="#" class="button dlm_upload_file" data-choose="<?php _e( 'Choose a file', 'woocommerce' ); ?>" data-update="<?php _e( 'Insert file URL', 'woocommerce' ); ?>"><?php _e( 'Upload file', 'download_monitor' ); ?></a>
|
22 |
+
<a href="#" class="button browse_for_file"><?php _e( 'Browse for file', 'download_monitor' ); ?></a>
|
23 |
+
</p>
|
24 |
+
|
25 |
+
</td>
|
26 |
+
</tr>
|
27 |
+
<tr>
|
28 |
+
<td>
|
29 |
+
<label><?php _e( 'Download count', 'download_monitor' ); ?>:</label>
|
30 |
+
<input type="text" class="short" name="downloadable_file_download_count[<?php echo $i; ?>]" placeholder="<?php echo $file_download_count; ?>" />
|
31 |
+
</td>
|
32 |
+
</tr>
|
33 |
+
<tr>
|
34 |
+
<td>
|
35 |
+
<label><?php _e('File Date', 'download_monitor'); ?>:</label>
|
36 |
+
<input type="text" class="date-picker-field" name="downloadable_file_date[<?php echo $i; ?>]" maxlength="10" value="<?php echo date('Y-m-d', strtotime( $file_post_date ) ); ?>" /> @ <input type="text" class="hour" placeholder="<?php _e('h', 'download_monitor') ?>" name="downloadable_file_date_hour[<?php echo $i; ?>]" maxlength="2" size="2" value="<?php echo date('H', strtotime( $file_post_date ) ); ?>" />:<input type="text" class="minute" placeholder="<?php _e('m', 'download_monitor') ?>" name="downloadable_file_date_minute[<?php echo $i; ?>]" maxlength="2" size="2" value="<?php echo date('i', strtotime( $file_post_date ) ); ?>" />
|
37 |
+
</td>
|
38 |
+
</tr>
|
39 |
+
</tbody>
|
40 |
+
</table>
|
41 |
+
</div>
|
includes/admin/uaparser/CHANGELOG
ADDED
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
THIS CHANGELOG IS AN ATTEMPT TO DOCUMENT CHANGES TO THIS PROJECT.
|
2 |
+
SUPER MINOR REVISION NUMBERS WON'T SHOW UP IN GITHUB BUT IT'LL HELP
|
3 |
+
ME ORGANIZE WHEN I MADE A SET OF FIXES
|
4 |
+
|
5 |
+
UAP-2.1.1
|
6 |
+
- FIX: making sure patch minor is being populated correctly when showing a mismatch
|
7 |
+
|
8 |
+
UAP-2.1.0
|
9 |
+
- ADD: support for custom regexes.json files (via @pravindahal)
|
10 |
+
- FIX: formerly private vars/functions are now protected (via @pravindahal)
|
11 |
+
- FIX: command line tool gets 'pretty' option for PHP 5.4 users (via @skyzyx)
|
12 |
+
- FIX: refactored the regexes.yaml test suite
|
13 |
+
- FIX: now check to see if allow_url_fopen is set to 'On' before trying to download the YAML file from the command line
|
14 |
+
- THX: thanks to @pravindahal and @skyzyx for the pull requests
|
15 |
+
|
16 |
+
UAP-2.0.1
|
17 |
+
- FIX: renamed uaParser, osParser, & deviceParser to uaParse, osParse, & deviceParse to address a bug with uaParser being recognized as the contruct function for the overall lib
|
18 |
+
- FIX: updated the test lib so that device failures are properly formatted
|
19 |
+
|
20 |
+
UAP-2.0.0
|
21 |
+
- ADD: toString() converts the version bits and family into a simple string
|
22 |
+
- ADD: toVersionString() converts the version bits into a simple string
|
23 |
+
- ADD: toFullString() combines the UA and OS family and version bits
|
24 |
+
- ADD: "convert" flag for uaparser-cli.php
|
25 |
+
- ADD: "pull & save just regexes.yaml" flag for uaparser-cli.php
|
26 |
+
- FIX: library is now a dynamic class
|
27 |
+
- FIX: attributes are now nested & populated like the other ua-parser libraries (e.g. $result->family is now $result->ua->family)
|
28 |
+
- FIX: uaParser(), osParser(), and deviceParser() are now public functions
|
29 |
+
- FIX: saves regexes.yaml as JSON for better performance
|
30 |
+
- FIX: removed the __DIR__ "fix"
|
31 |
+
- FIX: Apache log parsing now returns results when UA or OS families are set to "Other" and the device is listed as a smartphone or generic feature phone
|
32 |
+
- FIX: all tabs are now spaces
|
33 |
+
- FIX: a UA is now run against all three parsers
|
34 |
+
- FIX: renamed $debug var to $log to better reflect what it does
|
35 |
+
- DEL: is* boolean attributes (e.g. isMobile) have been removed
|
36 |
+
- DEL: will no longer auto-parse $_SERVER['HTTP_USER_AGENT'] if available
|
37 |
+
- DEL: tests no longer run against pgts_browser_list.yaml
|
38 |
+
- THX: thanks to @rjd22 for the dynamic class code/fix
|
39 |
+
|
40 |
+
UAP-1.5.0
|
41 |
+
- ADD: command line interface is now in its own file (via @Synchro)
|
42 |
+
- ADD: command line utility now supports parsing an Apache log file & recording the results
|
43 |
+
- ADD: command line utility can now parse a supplied user-agent string and push out a simple list or JSON
|
44 |
+
- ADD: test suite that uses the ua-parser project's test resources
|
45 |
+
- FIX: numerous comment & spacing fixes (via @Synchro & @Krinkle)
|
46 |
+
- FIX: remove PHP4 version of spyc (via @Synchro)
|
47 |
+
- FIX: remove .svn dirs in spyc (via @lopezdonaque)
|
48 |
+
- FIX: notes that the PHP 5.2 fix really was for 5.1 (via @Synchro) (knew this, i was lazy)
|
49 |
+
- FIX: lib now returns an object no matter what. now matches other ua-parser libs (via @Krinkle)
|
50 |
+
- FIX: checks that $_SERVER attr is set before including it. should be better for command line use.
|
51 |
+
- FIX: family attr now properly set in an edge case
|
52 |
+
- FIX: if regexes.yaml picks up bad slashes the PHP lib will account for it (e.g. GoogleTV regex)
|
53 |
+
- THX: thanks to @Krinkle and @Synchro for the numerous fixes
|
54 |
+
|
55 |
+
UAP-1.4.5
|
56 |
+
- FIX: an embarrassing debug print survived the last edit
|
57 |
+
- THX: thanks to @memakeit for dropping the bug report
|
58 |
+
|
59 |
+
UAP-1.4.4
|
60 |
+
- FIX: made sure that the regex file is only loaded once if running the library multiple times. performance boost.
|
61 |
+
- FIX: added support for identifying various game devices as mobile devices
|
62 |
+
- THX: thanks to @rjd22 for pointing out the perf issue
|
63 |
+
|
64 |
+
UAP-1.4.3
|
65 |
+
- FIX: added support for patch & family attributes to sort of match the other libraries
|
66 |
+
|
67 |
+
UAP-1.4.2
|
68 |
+
- FIX: notice if regexes.yaml is missing parens (e.g. match $1) for device & os names
|
69 |
+
|
70 |
+
UAP-1.4.1
|
71 |
+
- FIX: notice when using UAParser from the command line
|
72 |
+
|
73 |
+
UAP-1.4.0
|
74 |
+
- ADD: silent mode for the UA::get() method
|
75 |
+
- ADD: nobackup mode for the UA::get() method
|
76 |
+
- ADD: example of how to do a redirect with ua-parser-php
|
77 |
+
- The following were changes to regexes.yaml:
|
78 |
+
---- ADD: support for Google Earth browser
|
79 |
+
---- ADD: another regex for Firefox Mobile
|
80 |
+
---- ADD: support for Firefox Alpha builds
|
81 |
+
---- ADD: support for Sogou Explorer
|
82 |
+
---- ADD: support for the Raven for Mac browser
|
83 |
+
---- ADD: support for WebKit Nightly builds (though slightly pointless)
|
84 |
+
---- FIX: better pattern matching for the Pale Moon browser
|
85 |
+
|
86 |
+
UAP-v1.3.2
|
87 |
+
- FIX: addressed false "tablet" classification for opera mobile & mini on android
|
88 |
+
- The following were changes to regexes.yaml:
|
89 |
+
---- ADD: support for Tizen Browser (aka SLP Browser) from Samsung
|
90 |
+
---- FIX: support for a new look Polaris 8.0 user agent string
|
91 |
+
---- FIX: modified where the Epiphany Browser check happens
|
92 |
+
|
93 |
+
UAP-v1.3.1
|
94 |
+
- FIX: now doing some sanity cleaning on the user agent strings
|
95 |
+
- FIX: added a smarter default if the user agent isn't recognized at all
|
96 |
+
|
97 |
+
UAP-v1.3.0
|
98 |
+
- FIX: now points to Tobie's ua-parser project for the latest greatest YAML file
|
99 |
+
- FIX: YAML file is now standardized as regexes.yaml instead of user_agents_regex.yaml
|
100 |
+
- FIX: minor NOTICE issues resolved for very select UAs
|
101 |
+
|
102 |
+
UAP-v1.2.2
|
103 |
+
- The following were changes to user_agents_regex.yaml:
|
104 |
+
---- ADD: support for UC Browser
|
105 |
+
|
106 |
+
UAP-v1.2.1
|
107 |
+
- The following were changes to user_agents_regex.yaml:
|
108 |
+
---- ADD: support for android 4 user agents that have a dash in them
|
109 |
+
|
110 |
+
UAP-v1.2.0
|
111 |
+
- FIX: should be compatible with PHP 5.2
|
112 |
+
- FIX: addressed STRICT mode errors
|
113 |
+
- FIX: addressed NOTICE for a missing variable
|
114 |
+
- FIX: if isTablet is set to true then isMobile is set to false (mobile to me means phone)
|
115 |
+
- THX: Thanks to Mike Bond of WVU Libraries for pointing out the 5.2 incompatibility
|
116 |
+
|
117 |
+
UAP-v1.1.0
|
118 |
+
- FIX: a number of fixes from bryan shelton
|
119 |
+
- The following were changes to user_agents_regex.yaml:
|
120 |
+
---- ADD: support for Chrome Mobile
|
121 |
+
|
122 |
+
UAP-v1.0.0
|
123 |
+
- just because i don't expect to update this anytime soon and ppl report it's working
|
124 |
+
|
125 |
+
UAP-v0.3.1
|
126 |
+
- FIX: swapped nil for null in parse()
|
127 |
+
- FIX: smarter/saner defaults
|
128 |
+
- FIX: now using isset() for family_replacement
|
129 |
+
- THX: thanks to bryan shelton for these fixes
|
130 |
+
|
131 |
+
UAP-v0.3.0
|
132 |
+
- ADD: can now supply a specific UA to be checked
|
133 |
+
- ADD: if the UA contains 'tablet' isTablet is marked true
|
134 |
+
- ADD: for certain mobile OSs they report a desktop browser. marking them mobile now.
|
135 |
+
- FIX: tablet listing should now be better
|
136 |
+
- FIX: the list of mobile browsers was updated
|
137 |
+
- FIX: made sure that certain checks won't fail as "false" if a version number was a 0
|
138 |
+
- FIX: for the device check, if it returns spider as a result it no longer marks it as mobile
|
139 |
+
- FIX: added more mobile browsers to that specific check
|
140 |
+
- The following were changes to user_agents_regex.yaml:
|
141 |
+
---- ADD: symphony, minimo, teleca, semc, up.browser, bunjaloo, jasmine, & brew browsers supported
|
142 |
+
---- ADD: windows mobile 6.5 os support
|
143 |
+
---- ADD: amoi, asus, bird, dell, docomo, huawei, i-mate, kyocera, lenovo, lg, microsoft kind,
|
144 |
+
motorola, philips, samsung, softbank, & sony ericsson device checks
|
145 |
+
---- FIX: mobile firefox, opera mobile & mini, obigo, polaris, nokiabrowser, ie mobile,
|
146 |
+
android, & mobile safari browser checks
|
147 |
+
---- FIX: iOS support
|
148 |
+
---- FIX: htc, android, palm/hp, kindle, ios, generic feature phones & spider device checks
|
149 |
+
|
150 |
+
UAP-v0.2.0
|
151 |
+
- ADD: added isMobile support
|
152 |
+
- ADD: added isTablet support
|
153 |
+
- ADD: added isComputer support
|
154 |
+
- ADD: added isSpider support
|
155 |
+
|
156 |
+
UAP-v0.1.0
|
157 |
+
- The following were changes to user_agents_regex.yaml:
|
158 |
+
---- expanded support for Symbia & Nokia Devices,
|
159 |
+
---- cleaned up some slashies,
|
160 |
+
---- added Mobile Safari as the family replacement for iOS devices,
|
161 |
+
---- better support for longer HTC device names
|
162 |
+
---- added feature phones to the device check
|
163 |
+
---- added generic smartphones to the device check
|
164 |
+
---- added AvantGo to the ua check
|
165 |
+
---- tweaked a lot of the nokia checks
|
166 |
+
---- added kindle support to the device section
|
167 |
+
---- added a generic catch for android devices.
|
168 |
+
---- added support for blackberry devices
|
169 |
+
---- changed the blackberry family to 'blackberry webkit' when it's a webkit browser
|
includes/admin/uaparser/LICENSE
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Copyright (c) 2011-2012 Dave Olsen, http://dmolsen.com
|
2 |
+
Licensed under the MIT license
|
3 |
+
|
4 |
+
ua-parser-php is a PHP-based pseudo-port of the ua-parser project. Learn more about the ua-parser project at:
|
5 |
+
|
6 |
+
http://code.google.com/p/ua-parser/
|
7 |
+
|
8 |
+
The user agents data from the ua-parser project is licensed under the Apache license.
|
9 |
+
spyc-0.5, for loading the YAML, is licensed under the MIT license.
|
10 |
+
The initial list of generic feature phones & smartphones came from Mobile Web OSP under the MIT license
|
11 |
+
The initial list of spiders was taken from Yiibu's profile project under the MIT license.
|
includes/admin/uaparser/README.md
ADDED
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# ua-parser PHP Library #
|
2 |
+
|
3 |
+
This is the PHP library for the [ua-parser](https://github.com/tobie/ua-parser) project.
|
4 |
+
|
5 |
+
## v2.0 Changes ##
|
6 |
+
|
7 |
+
v2.0 of the PHP library, released in December 2012, marked a huge transition from the previous pseudo-port of `ua-parser` to a true port that matches up well with the other libraries in the `ua-parser` repo. The primary changes:
|
8 |
+
|
9 |
+
* the `UAParser` class is now dynamic
|
10 |
+
* properties are nested _(e.g. $result->family is now $result->ua->family)_
|
11 |
+
* a user agent string is now required when using `parse()`. the auto-magical "use the server provided UA" is no longer supported.
|
12 |
+
* `uaParse()`, `osParse()`, and `deviceParse()` are public and can be used to just return those select bits for a given user agent string.
|
13 |
+
* the `is*` boolean properties _(e.g. isMobile)_ have been dropped. they now exist as part of the `ua-classifier` project.
|
14 |
+
|
15 |
+
Please refer to the `CHANGELOG` for the full list of changes.
|
16 |
+
|
17 |
+
## Demo ##
|
18 |
+
|
19 |
+
You can [test the PHP library](http://uaparser.dmolsen.com/) with your browser.
|
20 |
+
|
21 |
+
## Usage ##
|
22 |
+
|
23 |
+
Straightforward:
|
24 |
+
|
25 |
+
```php
|
26 |
+
require("uaparser.php");
|
27 |
+
|
28 |
+
$ua = "Mozilla/5.0 (Macintosh; Intel Ma...";
|
29 |
+
|
30 |
+
$parser = new UAParser;
|
31 |
+
$result = $parser->parse($ua);
|
32 |
+
|
33 |
+
print $result->ua->family; // Safari
|
34 |
+
print $result->ua->major; // 6
|
35 |
+
print $result->ua->minor; // 0
|
36 |
+
print $result->ua->patch; // 2
|
37 |
+
print $result->ua->toString; // Safari 6.0.2
|
38 |
+
print $result->ua->toVersionString; // 6.0.2
|
39 |
+
|
40 |
+
print $result->os->family; // Mac OS X
|
41 |
+
print $result->os->major; // 10
|
42 |
+
print $result->os->minor; // 7
|
43 |
+
print $result->os->patch; // 5
|
44 |
+
print $result->os->patch_minor; // [null]
|
45 |
+
print $result->os->toString; // Mac OS X 10.7.5
|
46 |
+
print $result->os->toVersionString; // 10.7.5
|
47 |
+
|
48 |
+
print $result->device->family; // Other
|
49 |
+
|
50 |
+
print $result->toFullString; // Safari 6.0.2/Mac OS X 10.7.5
|
51 |
+
print $result->uaOriginal; // Mozilla/5.0 (Macintosh; Intel Ma...
|
52 |
+
```
|
53 |
+
|
54 |
+
## Using Your Own Custom regexes.json File ##
|
55 |
+
|
56 |
+
You can use your own `regexes.json` file if you've customized the official file. I *strongly* encourage you to push back any changes you may have so others can benefit. That said, to use your own do the following:
|
57 |
+
|
58 |
+
```php
|
59 |
+
require("uaparser.php");
|
60 |
+
|
61 |
+
$parser = new UAParser("path/to/custom/regexes.json");
|
62 |
+
```
|
63 |
+
|
64 |
+
## Using ua-parser PHP Library from the Command Line ##
|
65 |
+
|
66 |
+
A command line utility is now included with the PHP library. The following commands are supported:
|
67 |
+
|
68 |
+
### Get Usage Info
|
69 |
+
|
70 |
+
Provides simple usage information:
|
71 |
+
|
72 |
+
php uaparser-cli.php
|
73 |
+
|
74 |
+
### Update the regexes.json File
|
75 |
+
|
76 |
+
Fetches an updated YAML file for `ua-parser` and overwrites the current JSON file. You can use the following as part of a cron job that runs nightly.
|
77 |
+
|
78 |
+
php uaparser-cli.php -g [-s] [-n]
|
79 |
+
|
80 |
+
By default is verbose. Use `-s` to turn that feature off. By default creates a back-up. Use `-n` to turn that feature off.
|
81 |
+
|
82 |
+
### Convert an Existing regexes.yaml File to regexes.json
|
83 |
+
|
84 |
+
With the change to v2.0 you may have an existing and customized YAML file for `ua-parser`. Use the following to convert it to JSON.
|
85 |
+
|
86 |
+
php uaparser-cli.php -c [-s] [-n]
|
87 |
+
|
88 |
+
By default is verbose. Use `-s` to turn that feature off. By default creates a back-up. Use `-n` to turn that feature off.
|
89 |
+
|
90 |
+
### Grab Just the Latest regexes.yaml File From the Repository
|
91 |
+
|
92 |
+
If you need to add a new UA it's easier to edit the original YAML and then convert it to JSON.
|
93 |
+
|
94 |
+
php uaparser-cli.php -y
|
95 |
+
|
96 |
+
Fetches an updated YAML file. *Warning:* This method overwrites any existing `regexes.yaml` file.
|
97 |
+
|
98 |
+
### Parse an Apache Log File
|
99 |
+
|
100 |
+
Parses the supplied Apache log file to test UAParser.php. Saves the UA to a file when the UA or OS family aren't recognized or when the UA is listed as a generic smartphone or as a generic feature phone.
|
101 |
+
|
102 |
+
php uaparser-cli.php -l "/path/to/apache/logfile"
|
103 |
+
|
104 |
+
|
105 |
+
### Parse a Single User Agent String
|
106 |
+
|
107 |
+
Parses a user agent string and dumps the results as a list.
|
108 |
+
|
109 |
+
php uaparser-cli.php [-p] [-j] "your user agent string"
|
110 |
+
|
111 |
+
Use the `-j` flag to print the result as JSON. Use the `-p` flag to pretty print the JSON result when using PHP 5.4+.
|
112 |
+
|
113 |
+
## Credits ##
|
114 |
+
|
115 |
+
Thanks to the [original ua-parser team](http://code.google.com/p/ua-parser/people/list) for making the YAML file available for others to build upon.
|
116 |
+
|
117 |
+
Also, many thanks to the following major contributors to the PHP library:
|
118 |
+
|
119 |
+
* Bryan Shelton
|
120 |
+
* Michael Bond
|
121 |
+
* @rjd22
|
122 |
+
* Timo Tijhof
|
123 |
+
* Marcus Bointon
|
124 |
+
* Ryan Parman
|
125 |
+
* Pravin Dahal
|
includes/admin/uaparser/lib/json/JSON.php
ADDED
@@ -0,0 +1,867 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?
|
2 |
+
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
3 |
+
/**
|
4 |
+
* Converts to and from JSON format.
|
5 |
+
*
|
6 |
+
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
7 |
+
* format. It is easy for humans to read and write. It is easy for machines
|
8 |
+
* to parse and generate. It is based on a subset of the JavaScript
|
9 |
+
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
10 |
+
* This feature can also be found in Python. JSON is a text format that is
|
11 |
+
* completely language independent but uses conventions that are familiar
|
12 |
+
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
13 |
+
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
14 |
+
* ideal data-interchange language.
|
15 |
+
*
|
16 |
+
* This package provides a simple encoder and decoder for JSON notation. It
|
17 |
+
* is intended for use with client-side Javascript applications that make
|
18 |
+
* use of HTTPRequest to perform server communication functions - data can
|
19 |
+
* be encoded into JSON notation for use in a client-side javascript, or
|
20 |
+
* decoded from incoming Javascript requests. JSON format is native to
|
21 |
+
* Javascript, and can be directly eval()'ed with no further parsing
|
22 |
+
* overhead
|
23 |
+
*
|
24 |
+
* All strings should be in ASCII or UTF-8 format!
|
25 |
+
*
|
26 |
+
* LICENSE: Redistribution and use in source and binary forms, with or
|
27 |
+
* without modification, are permitted provided that the following
|
28 |
+
* conditions are met: Redistributions of source code must retain the
|
29 |
+
* above copyright notice, this list of conditions and the following
|
30 |
+
* disclaimer. Redistributions in binary form must reproduce the above
|
31 |
+
* copyright notice, this list of conditions and the following disclaimer
|
32 |
+
* in the documentation and/or other materials provided with the
|
33 |
+
* distribution.
|
34 |
+
*
|
35 |
+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
36 |
+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
37 |
+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
38 |
+
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
39 |
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
40 |
+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
41 |
+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
42 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
43 |
+
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
44 |
+
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
45 |
+
* DAMAGE.
|
46 |
+
*
|
47 |
+
* @category
|
48 |
+
* @package Services_JSON
|
49 |
+
* @author Michal Migurski <mike-json@teczno.com>
|
50 |
+
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
51 |
+
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
52 |
+
* @copyright 2005 Michal Migurski
|
53 |
+
* @version CVS: $Id: JSON.php 292911 2010-01-02 04:04:10Z alan_k $
|
54 |
+
* @license http://www.opensource.org/licenses/bsd-license.php
|
55 |
+
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
56 |
+
*/
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
60 |
+
*/
|
61 |
+
define('SERVICES_JSON_SLICE', 1);
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
65 |
+
*/
|
66 |
+
define('SERVICES_JSON_IN_STR', 2);
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
70 |
+
*/
|
71 |
+
define('SERVICES_JSON_IN_ARR', 3);
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
75 |
+
*/
|
76 |
+
define('SERVICES_JSON_IN_OBJ', 4);
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Marker constant for Services_JSON::decode(), used to flag stack state
|
80 |
+
*/
|
81 |
+
define('SERVICES_JSON_IN_CMT', 5);
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Behavior switch for Services_JSON::decode()
|
85 |
+
*/
|
86 |
+
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Behavior switch for Services_JSON::decode()
|
90 |
+
*/
|
91 |
+
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Converts to and from JSON format.
|
95 |
+
*
|
96 |
+
* Brief example of use:
|
97 |
+
*
|
98 |
+
* <code>
|
99 |
+
* // create a new instance of Services_JSON
|
100 |
+
* $json = new Services_JSON();
|
101 |
+
*
|
102 |
+
* // convert a complexe value to JSON notation, and send it to the browser
|
103 |
+
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
|
104 |
+
* $output = $json->encode($value);
|
105 |
+
*
|
106 |
+
* print($output);
|
107 |
+
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
|
108 |
+
*
|
109 |
+
* // accept incoming POST data, assumed to be in JSON notation
|
110 |
+
* $input = file_get_contents('php://input', 1000000);
|
111 |
+
* $value = $json->decode($input);
|
112 |
+
* </code>
|
113 |
+
*/
|
114 |
+
class Services_JSON
|
115 |
+
{
|
116 |
+
/**
|
117 |
+
* constructs a new JSON instance
|
118 |
+
*
|
119 |
+
* @param int $use object behavior flags; combine with boolean-OR
|
120 |
+
*
|
121 |
+
* possible values:
|
122 |
+
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
|
123 |
+
* "{...}" syntax creates associative arrays
|
124 |
+
* instead of objects in decode().
|
125 |
+
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
|
126 |
+
* Values which can't be encoded (e.g. resources)
|
127 |
+
* appear as NULL instead of throwing errors.
|
128 |
+
* By default, a deeply-nested resource will
|
129 |
+
* bubble up with an error, so all return values
|
130 |
+
* from encode() should be checked with isError()
|
131 |
+
*/
|
132 |
+
function Services_JSON($use = 0)
|
133 |
+
{
|
134 |
+
$this->use = $use;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* convert a string from one UTF-16 char to one UTF-8 char
|
139 |
+
*
|
140 |
+
* Normally should be handled by mb_convert_encoding, but
|
141 |
+
* provides a slower PHP-only method for installations
|
142 |
+
* that lack the multibye string extension.
|
143 |
+
*
|
144 |
+
* @param string $utf16 UTF-16 character
|
145 |
+
* @return string UTF-8 character
|
146 |
+
* @access private
|
147 |
+
*/
|
148 |
+
function utf162utf8($utf16)
|
149 |
+
{
|
150 |
+
// oh please oh please oh please oh please oh please
|
151 |
+
if(function_exists('mb_convert_encoding')) {
|
152 |
+
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
153 |
+
}
|
154 |
+
|
155 |
+
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
|
156 |
+
|
157 |
+
switch(true) {
|
158 |
+
case ((0x7F & $bytes) == $bytes):
|
159 |
+
// this case should never be reached, because we are in ASCII range
|
160 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
161 |
+
return chr(0x7F & $bytes);
|
162 |
+
|
163 |
+
case (0x07FF & $bytes) == $bytes:
|
164 |
+
// return a 2-byte UTF-8 character
|
165 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
166 |
+
return chr(0xC0 | (($bytes >> 6) & 0x1F))
|
167 |
+
. chr(0x80 | ($bytes & 0x3F));
|
168 |
+
|
169 |
+
case (0xFFFF & $bytes) == $bytes:
|
170 |
+
// return a 3-byte UTF-8 character
|
171 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
172 |
+
return chr(0xE0 | (($bytes >> 12) & 0x0F))
|
173 |
+
. chr(0x80 | (($bytes >> 6) & 0x3F))
|
174 |
+
. chr(0x80 | ($bytes & 0x3F));
|
175 |
+
}
|
176 |
+
|
177 |
+
// ignoring UTF-32 for now, sorry
|
178 |
+
return '';
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* convert a string from one UTF-8 char to one UTF-16 char
|
183 |
+
*
|
184 |
+
* Normally should be handled by mb_convert_encoding, but
|
185 |
+
* provides a slower PHP-only method for installations
|
186 |
+
* that lack the multibye string extension.
|
187 |
+
*
|
188 |
+
* @param string $utf8 UTF-8 character
|
189 |
+
* @return string UTF-16 character
|
190 |
+
* @access private
|
191 |
+
*/
|
192 |
+
function utf82utf16($utf8)
|
193 |
+
{
|
194 |
+
// oh please oh please oh please oh please oh please
|
195 |
+
if(function_exists('mb_convert_encoding')) {
|
196 |
+
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
197 |
+
}
|
198 |
+
|
199 |
+
switch(strlen($utf8)) {
|
200 |
+
case 1:
|
201 |
+
// this case should never be reached, because we are in ASCII range
|
202 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
203 |
+
return $utf8;
|
204 |
+
|
205 |
+
case 2:
|
206 |
+
// return a UTF-16 character from a 2-byte UTF-8 char
|
207 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
208 |
+
return chr(0x07 & (ord($utf8{0}) >> 2))
|
209 |
+
. chr((0xC0 & (ord($utf8{0}) << 6))
|
210 |
+
| (0x3F & ord($utf8{1})));
|
211 |
+
|
212 |
+
case 3:
|
213 |
+
// return a UTF-16 character from a 3-byte UTF-8 char
|
214 |
+
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
215 |
+
return chr((0xF0 & (ord($utf8{0}) << 4))
|
216 |
+
| (0x0F & (ord($utf8{1}) >> 2)))
|
217 |
+
. chr((0xC0 & (ord($utf8{1}) << 6))
|
218 |
+
| (0x7F & ord($utf8{2})));
|
219 |
+
}
|
220 |
+
|
221 |
+
// ignoring UTF-32 for now, sorry
|
222 |
+
return '';
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* encodes an arbitrary variable into JSON format (and sends JSON Header)
|
227 |
+
*
|
228 |
+
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
229 |
+
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
230 |
+
* if var is a strng, note that encode() always expects it
|
231 |
+
* to be in ASCII or UTF-8 format!
|
232 |
+
*
|
233 |
+
* @return mixed JSON string representation of input var or an error if a problem occurs
|
234 |
+
* @access public
|
235 |
+
*/
|
236 |
+
function encode($var)
|
237 |
+
{
|
238 |
+
header('Content-type: application/json');
|
239 |
+
return $this->encodeUnsafe($var);
|
240 |
+
}
|
241 |
+
/**
|
242 |
+
* encodes an arbitrary variable into JSON format without JSON Header - warning - may allow CSS!!!!)
|
243 |
+
*
|
244 |
+
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
245 |
+
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
246 |
+
* if var is a strng, note that encode() always expects it
|
247 |
+
* to be in ASCII or UTF-8 format!
|
248 |
+
*
|
249 |
+
* @return mixed JSON string representation of input var or an error if a problem occurs
|
250 |
+
* @access public
|
251 |
+
*/
|
252 |
+
function encodeUnsafe($var)
|
253 |
+
{
|
254 |
+
// see bug #16908 - regarding numeric locale printing
|
255 |
+
$lc = setlocale(LC_NUMERIC, 0);
|
256 |
+
setlocale(LC_NUMERIC, 'C');
|
257 |
+
$ret = $this->_encode($var);
|
258 |
+
setlocale(LC_NUMERIC, $lc);
|
259 |
+
return $ret;
|
260 |
+
|
261 |
+
}
|
262 |
+
/**
|
263 |
+
* PRIVATE CODE that does the work of encodes an arbitrary variable into JSON format
|
264 |
+
*
|
265 |
+
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
266 |
+
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
267 |
+
* if var is a strng, note that encode() always expects it
|
268 |
+
* to be in ASCII or UTF-8 format!
|
269 |
+
*
|
270 |
+
* @return mixed JSON string representation of input var or an error if a problem occurs
|
271 |
+
* @access public
|
272 |
+
*/
|
273 |
+
function _encode($var)
|
274 |
+
{
|
275 |
+
|
276 |
+
switch (gettype($var)) {
|
277 |
+
case 'boolean':
|
278 |
+
return $var ? 'true' : 'false';
|
279 |
+
|
280 |
+
case 'NULL':
|
281 |
+
return 'null';
|
282 |
+
|
283 |
+
case 'integer':
|
284 |
+
return (int) $var;
|
285 |
+
|
286 |
+
case 'double':
|
287 |
+
case 'float':
|
288 |
+
return (float) $var;
|
289 |
+
|
290 |
+
case 'string':
|
291 |
+
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
292 |
+
$ascii = '';
|
293 |
+
$strlen_var = strlen($var);
|
294 |
+
|
295 |
+
/*
|
296 |
+
* Iterate over every character in the string,
|
297 |
+
* escaping with a slash or encoding to UTF-8 where necessary
|
298 |
+
*/
|
299 |
+
for ($c = 0; $c < $strlen_var; ++$c) {
|
300 |
+
|
301 |
+
$ord_var_c = ord($var{$c});
|
302 |
+
|
303 |
+
switch (true) {
|
304 |
+
case $ord_var_c == 0x08:
|
305 |
+
$ascii .= '\b';
|
306 |
+
break;
|
307 |
+
case $ord_var_c == 0x09:
|
308 |
+
$ascii .= '\t';
|
309 |
+
break;
|
310 |
+
case $ord_var_c == 0x0A:
|
311 |
+
$ascii .= '\n';
|
312 |
+
break;
|
313 |
+
case $ord_var_c == 0x0C:
|
314 |
+
$ascii .= '\f';
|
315 |
+
break;
|
316 |
+
case $ord_var_c == 0x0D:
|
317 |
+
$ascii .= '\r';
|
318 |
+
break;
|
319 |
+
|
320 |
+
case $ord_var_c == 0x22:
|
321 |
+
case $ord_var_c == 0x2F:
|
322 |
+
case $ord_var_c == 0x5C:
|
323 |
+
// double quote, slash, slosh
|
324 |
+
$ascii .= '\\'.$var{$c};
|
325 |
+
break;
|
326 |
+
|
327 |
+
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
328 |
+
// characters U-00000000 - U-0000007F (same as ASCII)
|
329 |
+
$ascii .= $var{$c};
|
330 |
+
break;
|
331 |
+
|
332 |
+
case (($ord_var_c & 0xE0) == 0xC0):
|
333 |
+
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
334 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
335 |
+
if ($c+1 >= $strlen_var) {
|
336 |
+
$c += 1;
|
337 |
+
$ascii .= '?';
|
338 |
+
break;
|
339 |
+
}
|
340 |
+
|
341 |
+
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
|
342 |
+
$c += 1;
|
343 |
+
$utf16 = $this->utf82utf16($char);
|
344 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
345 |
+
break;
|
346 |
+
|
347 |
+
case (($ord_var_c & 0xF0) == 0xE0):
|
348 |
+
if ($c+2 >= $strlen_var) {
|
349 |
+
$c += 2;
|
350 |
+
$ascii .= '?';
|
351 |
+
break;
|
352 |
+
}
|
353 |
+
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
354 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
355 |
+
$char = pack('C*', $ord_var_c,
|
356 |
+
@ord($var{$c + 1}),
|
357 |
+
@ord($var{$c + 2}));
|
358 |
+
$c += 2;
|
359 |
+
$utf16 = $this->utf82utf16($char);
|
360 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
361 |
+
break;
|
362 |
+
|
363 |
+
case (($ord_var_c & 0xF8) == 0xF0):
|
364 |
+
if ($c+3 >= $strlen_var) {
|
365 |
+
$c += 3;
|
366 |
+
$ascii .= '?';
|
367 |
+
break;
|
368 |
+
}
|
369 |
+
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
370 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
371 |
+
$char = pack('C*', $ord_var_c,
|
372 |
+
ord($var{$c + 1}),
|
373 |
+
ord($var{$c + 2}),
|
374 |
+
ord($var{$c + 3}));
|
375 |
+
$c += 3;
|
376 |
+
$utf16 = $this->utf82utf16($char);
|
377 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
378 |
+
break;
|
379 |
+
|
380 |
+
case (($ord_var_c & 0xFC) == 0xF8):
|
381 |
+
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
382 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
383 |
+
if ($c+4 >= $strlen_var) {
|
384 |
+
$c += 4;
|
385 |
+
$ascii .= '?';
|
386 |
+
break;
|
387 |
+
}
|
388 |
+
$char = pack('C*', $ord_var_c,
|
389 |
+
ord($var{$c + 1}),
|
390 |
+
ord($var{$c + 2}),
|
391 |
+
ord($var{$c + 3}),
|
392 |
+
ord($var{$c + 4}));
|
393 |
+
$c += 4;
|
394 |
+
$utf16 = $this->utf82utf16($char);
|
395 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
396 |
+
break;
|
397 |
+
|
398 |
+
case (($ord_var_c & 0xFE) == 0xFC):
|
399 |
+
if ($c+5 >= $strlen_var) {
|
400 |
+
$c += 5;
|
401 |
+
$ascii .= '?';
|
402 |
+
break;
|
403 |
+
}
|
404 |
+
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
405 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
406 |
+
$char = pack('C*', $ord_var_c,
|
407 |
+
ord($var{$c + 1}),
|
408 |
+
ord($var{$c + 2}),
|
409 |
+
ord($var{$c + 3}),
|
410 |
+
ord($var{$c + 4}),
|
411 |
+
ord($var{$c + 5}));
|
412 |
+
$c += 5;
|
413 |
+
$utf16 = $this->utf82utf16($char);
|
414 |
+
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
415 |
+
break;
|
416 |
+
}
|
417 |
+
}
|
418 |
+
return '"'.$ascii.'"';
|
419 |
+
|
420 |
+
case 'array':
|
421 |
+
/*
|
422 |
+
* As per JSON spec if any array key is not an integer
|
423 |
+
* we must treat the the whole array as an object. We
|
424 |
+
* also try to catch a sparsely populated associative
|
425 |
+
* array with numeric keys here because some JS engines
|
426 |
+
* will create an array with empty indexes up to
|
427 |
+
* max_index which can cause memory issues and because
|
428 |
+
* the keys, which may be relevant, will be remapped
|
429 |
+
* otherwise.
|
430 |
+
*
|
431 |
+
* As per the ECMA and JSON specification an object may
|
432 |
+
* have any string as a property. Unfortunately due to
|
433 |
+
* a hole in the ECMA specification if the key is a
|
434 |
+
* ECMA reserved word or starts with a digit the
|
435 |
+
* parameter is only accessible using ECMAScript's
|
436 |
+
* bracket notation.
|
437 |
+
*/
|
438 |
+
|
439 |
+
// treat as a JSON object
|
440 |
+
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
441 |
+
$properties = array_map(array($this, 'name_value'),
|
442 |
+
array_keys($var),
|
443 |
+
array_values($var));
|
444 |
+
|
445 |
+
foreach($properties as $property) {
|
446 |
+
if(Services_JSON::isError($property)) {
|
447 |
+
return $property;
|
448 |
+
}
|
449 |
+
}
|
450 |
+
|
451 |
+
return '{' . join(',', $properties) . '}';
|
452 |
+
}
|
453 |
+
|
454 |
+
// treat it like a regular array
|
455 |
+
$elements = array_map(array($this, '_encode'), $var);
|
456 |
+
|
457 |
+
foreach($elements as $element) {
|
458 |
+
if(Services_JSON::isError($element)) {
|
459 |
+
return $element;
|
460 |
+
}
|
461 |
+
}
|
462 |
+
|
463 |
+
return '[' . join(',', $elements) . ']';
|
464 |
+
|
465 |
+
case 'object':
|
466 |
+
$vars = get_object_vars($var);
|
467 |
+
|
468 |
+
$properties = array_map(array($this, 'name_value'),
|
469 |
+
array_keys($vars),
|
470 |
+
array_values($vars));
|
471 |
+
|
472 |
+
foreach($properties as $property) {
|
473 |
+
if(Services_JSON::isError($property)) {
|
474 |
+
return $property;
|
475 |
+
}
|
476 |
+
}
|
477 |
+
|
478 |
+
return '{' . join(',', $properties) . '}';
|
479 |
+
|
480 |
+
default:
|
481 |
+
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
482 |
+
? 'null'
|
483 |
+
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
484 |
+
}
|
485 |
+
}
|
486 |
+
|
487 |
+
/**
|
488 |
+
* array-walking function for use in generating JSON-formatted name-value pairs
|
489 |
+
*
|
490 |
+
* @param string $name name of key to use
|
491 |
+
* @param mixed $value reference to an array element to be encoded
|
492 |
+
*
|
493 |
+
* @return string JSON-formatted name-value pair, like '"name":value'
|
494 |
+
* @access private
|
495 |
+
*/
|
496 |
+
function name_value($name, $value)
|
497 |
+
{
|
498 |
+
$encoded_value = $this->_encode($value);
|
499 |
+
|
500 |
+
if(Services_JSON::isError($encoded_value)) {
|
501 |
+
return $encoded_value;
|
502 |
+
}
|
503 |
+
|
504 |
+
return $this->_encode(strval($name)) . ':' . $encoded_value;
|
505 |
+
}
|
506 |
+
|
507 |
+
/**
|
508 |
+
* reduce a string by removing leading and trailing comments and whitespace
|
509 |
+
*
|
510 |
+
* @param $str string string value to strip of comments and whitespace
|
511 |
+
*
|
512 |
+
* @return string string value stripped of comments and whitespace
|
513 |
+
* @access private
|
514 |
+
*/
|
515 |
+
function reduce_string($str)
|
516 |
+
{
|
517 |
+
$str = preg_replace(array(
|
518 |
+
|
519 |
+
// eliminate single line comments in '// ...' form
|
520 |
+
'#^\s*//(.+)$#m',
|
521 |
+
|
522 |
+
// eliminate multi-line comments in '/* ... */' form, at start of string
|
523 |
+
'#^\s*/\*(.+)\*/#Us',
|
524 |
+
|
525 |
+
// eliminate multi-line comments in '/* ... */' form, at end of string
|
526 |
+
'#/\*(.+)\*/\s*$#Us'
|
527 |
+
|
528 |
+
), '', $str);
|
529 |
+
|
530 |
+
// eliminate extraneous space
|
531 |
+
return trim($str);
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* decodes a JSON string into appropriate variable
|
536 |
+
*
|
537 |
+
* @param string $str JSON-formatted string
|
538 |
+
*
|
539 |
+
* @return mixed number, boolean, string, array, or object
|
540 |
+
* corresponding to given JSON input string.
|
541 |
+
* See argument 1 to Services_JSON() above for object-output behavior.
|
542 |
+
* Note that decode() always returns strings
|
543 |
+
* in ASCII or UTF-8 format!
|
544 |
+
* @access public
|
545 |
+
*/
|
546 |
+
function decode($str)
|
547 |
+
{
|
548 |
+
$str = $this->reduce_string($str);
|
549 |
+
|
550 |
+
switch (strtolower($str)) {
|
551 |
+
case 'true':
|
552 |
+
return true;
|
553 |
+
|
554 |
+
case 'false':
|
555 |
+
return false;
|
556 |
+
|
557 |
+
case 'null':
|
558 |
+
return null;
|
559 |
+
|
560 |
+
default:
|
561 |
+
$m = array();
|
562 |
+
|
563 |
+
if (is_numeric($str)) {
|
564 |
+
// Lookie-loo, it's a number
|
565 |
+
|
566 |
+
// This would work on its own, but I'm trying to be
|
567 |
+
// good about returning integers where appropriate:
|
568 |
+
// return (float)$str;
|
569 |
+
|
570 |
+
// Return float or int, as appropriate
|
571 |
+
return ((float)$str == (integer)$str)
|
572 |
+
? (integer)$str
|
573 |
+
: (float)$str;
|
574 |
+
|
575 |
+
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
576 |
+
// STRINGS RETURNED IN UTF-8 FORMAT
|
577 |
+
$delim = substr($str, 0, 1);
|
578 |
+
$chrs = substr($str, 1, -1);
|
579 |
+
$utf8 = '';
|
580 |
+
$strlen_chrs = strlen($chrs);
|
581 |
+
|
582 |
+
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
583 |
+
|
584 |
+
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
585 |
+
$ord_chrs_c = ord($chrs{$c});
|
586 |
+
|
587 |
+
switch (true) {
|
588 |
+
case $substr_chrs_c_2 == '\b':
|
589 |
+
$utf8 .= chr(0x08);
|
590 |
+
++$c;
|
591 |
+
break;
|
592 |
+
case $substr_chrs_c_2 == '\t':
|
593 |
+
$utf8 .= chr(0x09);
|
594 |
+
++$c;
|
595 |
+
break;
|
596 |
+
case $substr_chrs_c_2 == '\n':
|
597 |
+
$utf8 .= chr(0x0A);
|
598 |
+
++$c;
|
599 |
+
break;
|
600 |
+
case $substr_chrs_c_2 == '\f':
|
601 |
+
$utf8 .= chr(0x0C);
|
602 |
+
++$c;
|
603 |
+
break;
|
604 |
+
case $substr_chrs_c_2 == '\r':
|
605 |
+
$utf8 .= chr(0x0D);
|
606 |
+
++$c;
|
607 |
+
break;
|
608 |
+
|
609 |
+
case $substr_chrs_c_2 == '\\"':
|
610 |
+
case $substr_chrs_c_2 == '\\\'':
|
611 |
+
case $substr_chrs_c_2 == '\\\\':
|
612 |
+
case $substr_chrs_c_2 == '\\/':
|
613 |
+
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
|
614 |
+
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
|
615 |
+
$utf8 .= $chrs{++$c};
|
616 |
+
}
|
617 |
+
break;
|
618 |
+
|
619 |
+
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
|
620 |
+
// single, escaped unicode character
|
621 |
+
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
|
622 |
+
. chr(hexdec(substr($chrs, ($c + 4), 2)));
|
623 |
+
$utf8 .= $this->utf162utf8($utf16);
|
624 |
+
$c += 5;
|
625 |
+
break;
|
626 |
+
|
627 |
+
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
|
628 |
+
$utf8 .= $chrs{$c};
|
629 |
+
break;
|
630 |
+
|
631 |
+
case ($ord_chrs_c & 0xE0) == 0xC0:
|
632 |
+
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
633 |
+
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
634 |
+
$utf8 .= substr($chrs, $c, 2);
|
635 |
+
++$c;
|
636 |
+
break;
|
637 |
+
|
638 |
+
case ($ord_chrs_c & 0xF0) == 0xE0:
|
639 |
+
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
640 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
641 |
+
$utf8 .= substr($chrs, $c, 3);
|
642 |
+
$c += 2;
|
643 |
+
break;
|
644 |
+
|
645 |
+
case ($ord_chrs_c & 0xF8) == 0xF0:
|
646 |
+
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
647 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
648 |
+
$utf8 .= substr($chrs, $c, 4);
|
649 |
+
$c += 3;
|
650 |
+
break;
|
651 |
+
|
652 |
+
case ($ord_chrs_c & 0xFC) == 0xF8:
|
653 |
+
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
654 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
655 |
+
$utf8 .= substr($chrs, $c, 5);
|
656 |
+
$c += 4;
|
657 |
+
break;
|
658 |
+
|
659 |
+
case ($ord_chrs_c & 0xFE) == 0xFC:
|
660 |
+
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
661 |
+
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
662 |
+
$utf8 .= substr($chrs, $c, 6);
|
663 |
+
$c += 5;
|
664 |
+
break;
|
665 |
+
|
666 |
+
}
|
667 |
+
|
668 |
+
}
|
669 |
+
|
670 |
+
return $utf8;
|
671 |
+
|
672 |
+
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
|
673 |
+
// array, or object notation
|
674 |
+
|
675 |
+
if ($str{0} == '[') {
|
676 |
+
$stk = array(SERVICES_JSON_IN_ARR);
|
677 |
+
$arr = array();
|
678 |
+
} else {
|
679 |
+
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
680 |
+
$stk = array(SERVICES_JSON_IN_OBJ);
|
681 |
+
$obj = array();
|
682 |
+
} else {
|
683 |
+
$stk = array(SERVICES_JSON_IN_OBJ);
|
684 |
+
$obj = new stdClass();
|
685 |
+
}
|
686 |
+
}
|
687 |
+
|
688 |
+
array_push($stk, array('what' => SERVICES_JSON_SLICE,
|
689 |
+
'where' => 0,
|
690 |
+
'delim' => false));
|
691 |
+
|
692 |
+
$chrs = substr($str, 1, -1);
|
693 |
+
$chrs = $this->reduce_string($chrs);
|
694 |
+
|
695 |
+
if ($chrs == '') {
|
696 |
+
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
697 |
+
return $arr;
|
698 |
+
|
699 |
+
} else {
|
700 |
+
return $obj;
|
701 |
+
|
702 |
+
}
|
703 |
+
}
|
704 |
+
|
705 |
+
//print("\nparsing {$chrs}\n");
|
706 |
+
|
707 |
+
$strlen_chrs = strlen($chrs);
|
708 |
+
|
709 |
+
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
710 |
+
|
711 |
+
$top = end($stk);
|
712 |
+
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
713 |
+
|
714 |
+
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
715 |
+
// found a comma that is not inside a string, array, etc.,
|
716 |
+
// OR we've reached the end of the character list
|
717 |
+
$slice = substr($chrs, $top['where'], ($c - $top['where']));
|
718 |
+
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
719 |
+
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
720 |
+
|
721 |
+
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
722 |
+
// we are in an array, so just push an element onto the stack
|
723 |
+
array_push($arr, $this->decode($slice));
|
724 |
+
|
725 |
+
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
726 |
+
// we are in an object, so figure
|
727 |
+
// out the property name and set an
|
728 |
+
// element in an associative array,
|
729 |
+
// for now
|
730 |
+
$parts = array();
|
731 |
+
|
732 |
+
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
733 |
+
// "name":value pair
|
734 |
+
$key = $this->decode($parts[1]);
|
735 |
+
$val = $this->decode($parts[2]);
|
736 |
+
|
737 |
+
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
738 |
+
$obj[$key] = $val;
|
739 |
+
} else {
|
740 |
+
$obj->$key = $val;
|
741 |
+
}
|
742 |
+
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
743 |
+
// name:value pair, where name is unquoted
|
744 |
+
$key = $parts[1];
|
745 |
+
$val = $this->decode($parts[2]);
|
746 |
+
|
747 |
+
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
748 |
+
$obj[$key] = $val;
|
749 |
+
} else {
|
750 |
+
$obj->$key = $val;
|
751 |
+
}
|
752 |
+
}
|
753 |
+
|
754 |
+
}
|
755 |
+
|
756 |
+
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
|
757 |
+
// found a quote, and we are not inside a string
|
758 |
+
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
|
759 |
+
//print("Found start of string at {$c}\n");
|
760 |
+
|
761 |
+
} elseif (($chrs{$c} == $top['delim']) &&
|
762 |
+
($top['what'] == SERVICES_JSON_IN_STR) &&
|
763 |
+
((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
|
764 |
+
// found a quote, we're in a string, and it's not escaped
|
765 |
+
// we know that it's not escaped becase there is _not_ an
|
766 |
+
// odd number of backslashes at the end of the string so far
|
767 |
+
array_pop($stk);
|
768 |
+
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
769 |
+
|
770 |
+
} elseif (($chrs{$c} == '[') &&
|
771 |
+
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
772 |
+
// found a left-bracket, and we are in an array, object, or slice
|
773 |
+
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
|
774 |
+
//print("Found start of array at {$c}\n");
|
775 |
+
|
776 |
+
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
777 |
+
// found a right-bracket, and we're in an array
|
778 |
+
array_pop($stk);
|
779 |
+
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
780 |
+
|
781 |
+
} elseif (($chrs{$c} == '{') &&
|
782 |
+
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
783 |
+
// found a left-brace, and we are in an array, object, or slice
|
784 |
+
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
|
785 |
+
//print("Found start of object at {$c}\n");
|
786 |
+
|
787 |
+
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
788 |
+
// found a right-brace, and we're in an object
|
789 |
+
array_pop($stk);
|
790 |
+
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
791 |
+
|
792 |
+
} elseif (($substr_chrs_c_2 == '/*') &&
|
793 |
+
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
794 |
+
// found a comment start, and we are in an array, object, or slice
|
795 |
+
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
|
796 |
+
$c++;
|
797 |
+
//print("Found start of comment at {$c}\n");
|
798 |
+
|
799 |
+
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
|
800 |
+
// found a comment end, and we're in one now
|
801 |
+
array_pop($stk);
|
802 |
+
$c++;
|
803 |
+
|
804 |
+
for ($i = $top['where']; $i <= $c; ++$i)
|
805 |
+
$chrs = substr_replace($chrs, ' ', $i, 1);
|
806 |
+
|
807 |
+
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
808 |
+
|
809 |
+
}
|
810 |
+
|
811 |
+
}
|
812 |
+
|
813 |
+
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
814 |
+
return (array)$arr;
|
815 |
+
|
816 |
+
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
817 |
+
return (array)$obj;
|
818 |
+
|
819 |
+
}
|
820 |
+
|
821 |
+
}
|
822 |
+
}
|
823 |
+
}
|
824 |
+
|
825 |
+
/**
|
826 |
+
* @todo Ultimately, this should just call PEAR::isError()
|
827 |
+
*/
|
828 |
+
function isError($data, $code = null)
|
829 |
+
{
|
830 |
+
if (class_exists('pear')) {
|
831 |
+
return PEAR::isError($data, $code);
|
832 |
+
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
833 |
+
is_subclass_of($data, 'services_json_error'))) {
|
834 |
+
return true;
|
835 |
+
}
|
836 |
+
|
837 |
+
return false;
|
838 |
+
}
|
839 |
+
}
|
840 |
+
|
841 |
+
if (class_exists('PEAR_Error')) {
|
842 |
+
|
843 |
+
class Services_JSON_Error extends PEAR_Error
|
844 |
+
{
|
845 |
+
function Services_JSON_Error($message = 'unknown error', $code = null,
|
846 |
+
$mode = null, $options = null, $userinfo = null)
|
847 |
+
{
|
848 |
+
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
849 |
+
}
|
850 |
+
}
|
851 |
+
|
852 |
+
} else {
|
853 |
+
|
854 |
+
/**
|
855 |
+
* @todo Ultimately, this class shall be descended from PEAR_Error
|
856 |
+
*/
|
857 |
+
class Services_JSON_Error
|
858 |
+
{
|
859 |
+
function Services_JSON_Error($message = 'unknown error', $code = null,
|
860 |
+
$mode = null, $options = null, $userinfo = null)
|
861 |
+
{
|
862 |
+
|
863 |
+
}
|
864 |
+
}
|
865 |
+
|
866 |
+
}
|
867 |
+
|
includes/admin/uaparser/lib/json/jsonwrapper.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once 'JSON.php';
|
4 |
+
|
5 |
+
function json_encode($arg) {
|
6 |
+
global $services_json;
|
7 |
+
if (!isset($services_json)) {
|
8 |
+
$services_json = new Services_JSON();
|
9 |
+
}
|
10 |
+
return $services_json->encode($arg);
|
11 |
+
}
|
12 |
+
|
13 |
+
function json_decode($arg) {
|
14 |
+
global $services_json;
|
15 |
+
if (!isset($services_json)) {
|
16 |
+
$services_json = new Services_JSON();
|
17 |
+
}
|
18 |
+
return $services_json->decode($arg);
|
19 |
+
}
|
20 |
+
|
21 |
+
?>
|
includes/admin/uaparser/lib/spyc-0.5/COPYING
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
The MIT License
|
2 |
+
|
3 |
+
Copyright (c) 2011 Vladimir Andersen
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in
|
13 |
+
all copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21 |
+
THE SOFTWARE.
|
includes/admin/uaparser/lib/spyc-0.5/README
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#
|
2 |
+
# S P Y C
|
3 |
+
# a simple php yaml class
|
4 |
+
#
|
5 |
+
# Load this README!
|
6 |
+
# >> $readme = Spyc::YAMLLoad('README');
|
7 |
+
#
|
8 |
+
--- %YAML:1.1
|
9 |
+
title: Spyc -- a Simple PHP YAML Class
|
10 |
+
version: 0.5
|
11 |
+
authors: [chris wanstrath (chris@ozmm.org), vlad andersen (vlad.andersen@gmail.com)]
|
12 |
+
websites: [http://www.yaml.org, http://spyc.sourceforge.net]
|
13 |
+
license: [MIT License, http://www.opensource.org/licenses/mit-license.php]
|
14 |
+
copyright: "(c) 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen"
|
15 |
+
tested on: [php 5.2.x]
|
16 |
+
|
17 |
+
installation: >
|
18 |
+
Copy spyc.php to a directory you can
|
19 |
+
access with your YAML-ready PHP script.
|
20 |
+
|
21 |
+
That's it!
|
22 |
+
|
23 |
+
about: >
|
24 |
+
From www.yaml.org:
|
25 |
+
|
26 |
+
"YAML(tm) (rhymes with 'camel') is a human-friendly, cross language,
|
27 |
+
Unicode based data serialization language designed around the common
|
28 |
+
native data structures of agile programming languages. It is broadly
|
29 |
+
useful for programming needs ranging from configuration files to
|
30 |
+
Internet messaging to object persistence to data auditing. Together
|
31 |
+
with the Unicode standard for characters, the YAML specification provides
|
32 |
+
all the information necessary to understand YAML Version 1.1 and to
|
33 |
+
creating programs that process YAML information.
|
34 |
+
|
35 |
+
YAML(tm) is a balance of the following design goals:
|
36 |
+
- YAML documents are very readable by humans.
|
37 |
+
- YAML interacts well with scripting languages.
|
38 |
+
- YAML uses host languages' native data structures.
|
39 |
+
- YAML has a consistent information model.
|
40 |
+
- YAML enables stream-based processing.
|
41 |
+
- YAML is expressive and extensible.
|
42 |
+
- YAML is easy to implement."
|
43 |
+
|
44 |
+
YAML makes a lot of sense. It's easy to use, easy to learn, and cool.
|
45 |
+
As the lucky stiff named why once said, "YAML is a beacon of light."
|
46 |
+
|
47 |
+
If you're new to YAML, may we suggest YAML In Five Minutes:
|
48 |
+
- http://yaml.kwiki.org/?YamlInFiveMinutes
|
49 |
+
|
50 |
+
If you don't have five minutes, realize that this README is a completely
|
51 |
+
valid YAML document. Dig in, load this or any YAML file into an array
|
52 |
+
with Spyc and see how easy it is to translate friendly text into usable
|
53 |
+
data.
|
54 |
+
|
55 |
+
The purpose of Spyc is to provide a pure PHP alternative to Syck, a
|
56 |
+
simple API for loading and dumping YAML documents, a YAML loader which
|
57 |
+
understands a usable subset of the YAML spec, and to further spread
|
58 |
+
the glory of YAML to the PHP masses.
|
59 |
+
|
60 |
+
If you're at all hesitant ("usable subset of YAML?!"), navigate
|
61 |
+
http://yaml.org/start.html. Spyc completely understands the YAML
|
62 |
+
document shown there, a document which has features way beyond the
|
63 |
+
scope of what normal config files might require. Try it for yourself,
|
64 |
+
and then start enjoying the peace of mind YAML brings to your life.
|
65 |
+
|
66 |
+
meat and a few potatoes:
|
67 |
+
- concept: Loading a YAML document into PHP
|
68 |
+
brief: >
|
69 |
+
$yaml will become an array of all the data in wicked.yaml
|
70 |
+
code: |
|
71 |
+
|
72 |
+
include('spyc.php');
|
73 |
+
|
74 |
+
$yaml = Spyc::YAMLLoad('wicked.yaml');
|
75 |
+
|
76 |
+
- concept: Loading a YAML string into PHP
|
77 |
+
brief: >
|
78 |
+
$array will look like this:
|
79 |
+
array('A YAML','document in a','string')
|
80 |
+
code: |
|
81 |
+
|
82 |
+
include('spyc.php');
|
83 |
+
|
84 |
+
$yaml = '- A YAML\n- document in a\n- string.';
|
85 |
+
$array = Spyc::YAMLLoad($yaml);
|
86 |
+
|
87 |
+
- concept: Dumping a PHP array to YAML
|
88 |
+
brief: >
|
89 |
+
$yaml will become a string of a YAML document created from
|
90 |
+
$array.
|
91 |
+
code: |
|
92 |
+
|
93 |
+
include('spyc.php');
|
94 |
+
|
95 |
+
$array['name'] = 'chris';
|
96 |
+
$array['sport'] = 'curbing';
|
97 |
+
|
98 |
+
$yaml = Spyc::YAMLDump($array);
|
99 |
+
|
100 |
+
prior art:
|
101 |
+
- who: [Brian Ingerson, Clark Evans, Oren Ben-Kiki]
|
102 |
+
why?: >
|
103 |
+
The YAML spec is really a piece of work, and these guys
|
104 |
+
did a great job on it. A simple and elegant language like
|
105 |
+
YAML was a long time coming and it's refreshing to know
|
106 |
+
such able minded individuals took the task to heart and
|
107 |
+
executed it with cunning and strength. In addition to
|
108 |
+
their various noteworthy contributions to YAML parsers
|
109 |
+
and related projects, YAML.pm's README is a treasure trove
|
110 |
+
of information for knowledge seekers. Thanks, guys.
|
111 |
+
|
112 |
+
- who: why the lucky stiff
|
113 |
+
why?: >
|
114 |
+
As the author of Syck, the code used in Ruby for the language's
|
115 |
+
YAML class and methods, why is indirectly (directly?) responsible
|
116 |
+
for my first exposure to YAML (as a config file in a Ruby web-app)
|
117 |
+
and the countless hours I spent playing with this sheik new data
|
118 |
+
format afterwards. Syck's README is a YAML file and thus the
|
119 |
+
inspiration for this file and, even, this very piece of software.
|
120 |
+
|
121 |
+
- who: Steve Howell
|
122 |
+
why?: >
|
123 |
+
Python's YAML implementation. PyYAML's README file is also YAML,
|
124 |
+
so it too inspired the YAML format of this README file.
|
125 |
+
|
126 |
+
- who: [Rasmus Lerdorf, Zeev Suraski, Andi Gutmans, et al]
|
127 |
+
why?: >
|
128 |
+
PHP is great at what it does best. It's also paid a lot of my bills.
|
129 |
+
Thanks.
|
130 |
+
|
131 |
+
bugs:
|
132 |
+
report: >
|
133 |
+
Please see Spyc's Sourceforge project page for information on reporting bugs.
|
134 |
+
speed: >
|
135 |
+
This implementation was not designed for speed. Rather, it
|
136 |
+
was designed for those who need a pure PHP implementation of
|
137 |
+
a YAML parser and who are not overly concerned with performance.
|
138 |
+
If you want speed, check out Syck.
|
139 |
+
depth: >
|
140 |
+
This parser is by no means a comprehensive YAML parser. For supported
|
141 |
+
features and future plans, check the website.
|
142 |
+
unicode: >
|
143 |
+
YAML is supposed to be unicode, but for now we're just using ASCII.
|
144 |
+
PHP has crappy unicode support but who knows what the future holds.
|
145 |
+
|
146 |
+
resources:
|
147 |
+
- http://www.yaml.org
|
148 |
+
- http://www.yaml.org/spec/
|
149 |
+
- http://yaml.kwiki.org/?YamlInFiveMinutes
|
150 |
+
- http://www.whytheluckystiff.net/syck/
|
151 |
+
- http://yaml4r.sourceforge.net/cookbook/
|
152 |
+
|
153 |
+
thanks:
|
154 |
+
- Adam Wood
|
155 |
+
- Daniel Ferreira
|
156 |
+
- Aaron Jensen
|
157 |
+
- Mike Thornton
|
158 |
+
- Fabien Potencier
|
159 |
+
- Mustafa Kumas
|
includes/admin/uaparser/lib/spyc-0.5/examples/yaml-dump.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
#
|
4 |
+
# S P Y C
|
5 |
+
# a simple php yaml class
|
6 |
+
#
|
7 |
+
# Feel free to dump an array to YAML, and then to load that YAML back into an
|
8 |
+
# array. This is a good way to test the limitations of the parser and maybe
|
9 |
+
# learn some basic YAML.
|
10 |
+
#
|
11 |
+
|
12 |
+
include('../spyc.php');
|
13 |
+
|
14 |
+
$array[] = 'Sequence item';
|
15 |
+
$array['The Key'] = 'Mapped value';
|
16 |
+
$array[] = array('A sequence','of a sequence');
|
17 |
+
$array[] = array('first' => 'A sequence','second' => 'of mapped values');
|
18 |
+
$array['Mapped'] = array('A sequence','which is mapped');
|
19 |
+
$array['A Note'] = 'What if your text is too long?';
|
20 |
+
$array['Another Note'] = 'If that is the case, the dumper will probably fold your text by using a block. Kinda like this.';
|
21 |
+
$array['The trick?'] = 'The trick is that we overrode the default indent, 2, to 4 and the default wordwrap, 40, to 60.';
|
22 |
+
$array['Old Dog'] = "And if you want\n to preserve line breaks, \ngo ahead!";
|
23 |
+
$array['key:withcolon'] = "Should support this to";
|
24 |
+
|
25 |
+
$yaml = Spyc::YAMLDump($array,4,60);
|
includes/admin/uaparser/lib/spyc-0.5/examples/yaml-load.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
#
|
4 |
+
# S P Y C
|
5 |
+
# a simple php yaml class
|
6 |
+
#
|
7 |
+
# license: [MIT License, http://www.opensource.org/licenses/mit-license.php]
|
8 |
+
#
|
9 |
+
|
10 |
+
include('../spyc.php');
|
11 |
+
|
12 |
+
$array = Spyc::YAMLLoad('../spyc.yaml');
|
13 |
+
|
14 |
+
echo '<pre><a href="spyc.yaml">spyc.yaml</a> loaded into PHP:<br/>';
|
15 |
+
print_r($array);
|
16 |
+
echo '</pre>';
|
17 |
+
|
18 |
+
|
19 |
+
echo '<pre>YAML Data dumped back:<br/>';
|
20 |
+
echo Spyc::YAMLDump($array);
|
21 |
+
echo '</pre>';
|
includes/admin/uaparser/lib/spyc-0.5/spyc.php
ADDED
@@ -0,0 +1,1046 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Spyc -- A Simple PHP YAML Class
|
4 |
+
* @version 0.5
|
5 |
+
* @author Vlad Andersen <vlad.andersen@gmail.com>
|
6 |
+
* @author Chris Wanstrath <chris@ozmm.org>
|
7 |
+
* @link http://code.google.com/p/spyc/
|
8 |
+
* @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen
|
9 |
+
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
10 |
+
* @package Spyc
|
11 |
+
*/
|
12 |
+
|
13 |
+
if (!function_exists('spyc_load')) {
|
14 |
+
/**
|
15 |
+
* Parses YAML to array.
|
16 |
+
* @param string $string YAML string.
|
17 |
+
* @return array
|
18 |
+
*/
|
19 |
+
function spyc_load ($string) {
|
20 |
+
return Spyc::YAMLLoadString($string);
|
21 |
+
}
|
22 |
+
}
|
23 |
+
|
24 |
+
if (!function_exists('spyc_load_file')) {
|
25 |
+
/**
|
26 |
+
* Parses YAML to array.
|
27 |
+
* @param string $file Path to YAML file.
|
28 |
+
* @return array
|
29 |
+
*/
|
30 |
+
function spyc_load_file ($file) {
|
31 |
+
return Spyc::YAMLLoad($file);
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* The Simple PHP YAML Class.
|
37 |
+
*
|
38 |
+
* This class can be used to read a YAML file and convert its contents
|
39 |
+
* into a PHP array. It currently supports a very limited subsection of
|
40 |
+
* the YAML spec.
|
41 |
+
*
|
42 |
+
* Usage:
|
43 |
+
* <code>
|
44 |
+
* $Spyc = new Spyc;
|
45 |
+
* $array = $Spyc->load($file);
|
46 |
+
* </code>
|
47 |
+
* or:
|
48 |
+
* <code>
|
49 |
+
* $array = Spyc::YAMLLoad($file);
|
50 |
+
* </code>
|
51 |
+
* or:
|
52 |
+
* <code>
|
53 |
+
* $array = spyc_load_file($file);
|
54 |
+
* </code>
|
55 |
+
* @package Spyc
|
56 |
+
*/
|
57 |
+
class Spyc {
|
58 |
+
|
59 |
+
// SETTINGS
|
60 |
+
|
61 |
+
const REMPTY = "\0\0\0\0\0";
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Setting this to true will force YAMLDump to enclose any string value in
|
65 |
+
* quotes. False by default.
|
66 |
+
*
|
67 |
+
* @var bool
|
68 |
+
*/
|
69 |
+
public $setting_dump_force_quotes = false;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Setting this to true will forse YAMLLoad to use syck_load function when
|
73 |
+
* possible. False by default.
|
74 |
+
* @var bool
|
75 |
+
*/
|
76 |
+
public $setting_use_syck_is_possible = false;
|
77 |
+
|
78 |
+
|
79 |
+
|
80 |
+
/**#@+
|
81 |
+
* @access private
|
82 |
+
* @var mixed
|
83 |
+
*/
|
84 |
+
private $_dumpIndent;
|
85 |
+
private $_dumpWordWrap;
|
86 |
+
private $_containsGroupAnchor = false;
|
87 |
+
private $_containsGroupAlias = false;
|
88 |
+
private $path;
|
89 |
+
private $result;
|
90 |
+
private $LiteralPlaceHolder = '___YAML_Literal_Block___';
|
91 |
+
private $SavedGroups = array();
|
92 |
+
private $indent;
|
93 |
+
/**
|
94 |
+
* Path modifier that should be applied after adding current element.
|
95 |
+
* @var array
|
96 |
+
*/
|
97 |
+
private $delayedPath = array();
|
98 |
+
|
99 |
+
/**#@+
|
100 |
+
* @access public
|
101 |
+
* @var mixed
|
102 |
+
*/
|
103 |
+
public $_nodeId;
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Load a valid YAML string to Spyc.
|
107 |
+
* @param string $input
|
108 |
+
* @return array
|
109 |
+
*/
|
110 |
+
public function load ($input) {
|
111 |
+
return $this->__loadString($input);
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Load a valid YAML file to Spyc.
|
116 |
+
* @param string $file
|
117 |
+
* @return array
|
118 |
+
*/
|
119 |
+
public function loadFile ($file) {
|
120 |
+
return $this->__load($file);
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Load YAML into a PHP array statically
|
125 |
+
*
|
126 |
+
* The load method, when supplied with a YAML stream (string or file),
|
127 |
+
* will do its best to convert YAML in a file into a PHP array. Pretty
|
128 |
+
* simple.
|
129 |
+
* Usage:
|
130 |
+
* <code>
|
131 |
+
* $array = Spyc::YAMLLoad('lucky.yaml');
|
132 |
+
* print_r($array);
|
133 |
+
* </code>
|
134 |
+
* @access public
|
135 |
+
* @return array
|
136 |
+
* @param string $input Path of YAML file or string containing YAML
|
137 |
+
*/
|
138 |
+
public static function YAMLLoad($input) {
|
139 |
+
$Spyc = new Spyc;
|
140 |
+
return $Spyc->__load($input);
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Load a string of YAML into a PHP array statically
|
145 |
+
*
|
146 |
+
* The load method, when supplied with a YAML string, will do its best
|
147 |
+
* to convert YAML in a string into a PHP array. Pretty simple.
|
148 |
+
*
|
149 |
+
* Note: use this function if you don't want files from the file system
|
150 |
+
* loaded and processed as YAML. This is of interest to people concerned
|
151 |
+
* about security whose input is from a string.
|
152 |
+
*
|
153 |
+
* Usage:
|
154 |
+
* <code>
|
155 |
+
* $array = Spyc::YAMLLoadString("---\n0: hello world\n");
|
156 |
+
* print_r($array);
|
157 |
+
* </code>
|
158 |
+
* @access public
|
159 |
+
* @return array
|
160 |
+
* @param string $input String containing YAML
|
161 |
+
*/
|
162 |
+
public static function YAMLLoadString($input) {
|
163 |
+
$Spyc = new Spyc;
|
164 |
+
return $Spyc->__loadString($input);
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Dump YAML from PHP array statically
|
169 |
+
*
|
170 |
+
* The dump method, when supplied with an array, will do its best
|
171 |
+
* to convert the array into friendly YAML. Pretty simple. Feel free to
|
172 |
+
* save the returned string as nothing.yaml and pass it around.
|
173 |
+
*
|
174 |
+
* Oh, and you can decide how big the indent is and what the wordwrap
|
175 |
+
* for folding is. Pretty cool -- just pass in 'false' for either if
|
176 |
+
* you want to use the default.
|
177 |
+
*
|
178 |
+
* Indent's default is 2 spaces, wordwrap's default is 40 characters. And
|
179 |
+
* you can turn off wordwrap by passing in 0.
|
180 |
+
*
|
181 |
+
* @access public
|
182 |
+
* @return string
|
183 |
+
* @param array $array PHP array
|
184 |
+
* @param int $indent Pass in false to use the default, which is 2
|
185 |
+
* @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
|
186 |
+
*/
|
187 |
+
public static function YAMLDump($array,$indent = false,$wordwrap = false) {
|
188 |
+
$spyc = new Spyc;
|
189 |
+
return $spyc->dump($array,$indent,$wordwrap);
|
190 |
+
}
|
191 |
+
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Dump PHP array to YAML
|
195 |
+
*
|
196 |
+
* The dump method, when supplied with an array, will do its best
|
197 |
+
* to convert the array into friendly YAML. Pretty simple. Feel free to
|
198 |
+
* save the returned string as tasteful.yaml and pass it around.
|
199 |
+
*
|
200 |
+
* Oh, and you can decide how big the indent is and what the wordwrap
|
201 |
+
* for folding is. Pretty cool -- just pass in 'false' for either if
|
202 |
+
* you want to use the default.
|
203 |
+
*
|
204 |
+
* Indent's default is 2 spaces, wordwrap's default is 40 characters. And
|
205 |
+
* you can turn off wordwrap by passing in 0.
|
206 |
+
*
|
207 |
+
* @access public
|
208 |
+
* @return string
|
209 |
+
* @param array $array PHP array
|
210 |
+
* @param int $indent Pass in false to use the default, which is 2
|
211 |
+
* @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
|
212 |
+
*/
|
213 |
+
public function dump($array,$indent = false,$wordwrap = false) {
|
214 |
+
// Dumps to some very clean YAML. We'll have to add some more features
|
215 |
+
// and options soon. And better support for folding.
|
216 |
+
|
217 |
+
// New features and options.
|
218 |
+
if ($indent === false or !is_numeric($indent)) {
|
219 |
+
$this->_dumpIndent = 2;
|
220 |
+
} else {
|
221 |
+
$this->_dumpIndent = $indent;
|
222 |
+
}
|
223 |
+
|
224 |
+
if ($wordwrap === false or !is_numeric($wordwrap)) {
|
225 |
+
$this->_dumpWordWrap = 40;
|
226 |
+
} else {
|
227 |
+
$this->_dumpWordWrap = $wordwrap;
|
228 |
+
}
|
229 |
+
|
230 |
+
// New YAML document
|
231 |
+
$string = "---\n";
|
232 |
+
|
233 |
+
// Start at the base of the array and move through it.
|
234 |
+
if ($array) {
|
235 |
+
$array = (array)$array;
|
236 |
+
$previous_key = -1;
|
237 |
+
foreach ($array as $key => $value) {
|
238 |
+
if (!isset($first_key)) $first_key = $key;
|
239 |
+
$string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array);
|
240 |
+
$previous_key = $key;
|
241 |
+
}
|
242 |
+
}
|
243 |
+
return $string;
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Attempts to convert a key / value array item to YAML
|
248 |
+
* @access private
|
249 |
+
* @return string
|
250 |
+
* @param $key The name of the key
|
251 |
+
* @param $value The value of the item
|
252 |
+
* @param $indent The indent of the current node
|
253 |
+
*/
|
254 |
+
private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) {
|
255 |
+
if (is_array($value)) {
|
256 |
+
if (empty ($value))
|
257 |
+
return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array);
|
258 |
+
// It has children. What to do?
|
259 |
+
// Make it the right kind of item
|
260 |
+
$string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array);
|
261 |
+
// Add the indent
|
262 |
+
$indent += $this->_dumpIndent;
|
263 |
+
// Yamlize the array
|
264 |
+
$string .= $this->_yamlizeArray($value,$indent);
|
265 |
+
} elseif (!is_array($value)) {
|
266 |
+
// It doesn't have children. Yip.
|
267 |
+
$string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array);
|
268 |
+
}
|
269 |
+
return $string;
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Attempts to convert an array to YAML
|
274 |
+
* @access private
|
275 |
+
* @return string
|
276 |
+
* @param $array The array you want to convert
|
277 |
+
* @param $indent The indent of the current level
|
278 |
+
*/
|
279 |
+
private function _yamlizeArray($array,$indent) {
|
280 |
+
if (is_array($array)) {
|
281 |
+
$string = '';
|
282 |
+
$previous_key = -1;
|
283 |
+
foreach ($array as $key => $value) {
|
284 |
+
if (!isset($first_key)) $first_key = $key;
|
285 |
+
$string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array);
|
286 |
+
$previous_key = $key;
|
287 |
+
}
|
288 |
+
return $string;
|
289 |
+
} else {
|
290 |
+
return false;
|
291 |
+
}
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Returns YAML from a key and a value
|
296 |
+
* @access private
|
297 |
+
* @return string
|
298 |
+
* @param $key The name of the key
|
299 |
+
* @param $value The value of the item
|
300 |
+
* @param $indent The indent of the current node
|
301 |
+
*/
|
302 |
+
private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) {
|
303 |
+
// do some folding here, for blocks
|
304 |
+
if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false ||
|
305 |
+
strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos ($value, ' ') !== false ||
|
306 |
+
strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || strpos($value,"&") !== false || strpos($value, "'") !== false || strpos($value, "!") === 0 ||
|
307 |
+
substr ($value, -1, 1) == ':')
|
308 |
+
) {
|
309 |
+
$value = $this->_doLiteralBlock($value,$indent);
|
310 |
+
} else {
|
311 |
+
$value = $this->_doFolding($value,$indent);
|
312 |
+
}
|
313 |
+
|
314 |
+
if ($value === array()) $value = '[ ]';
|
315 |
+
if (in_array ($value, array ('true', 'TRUE', 'false', 'FALSE', 'y', 'Y', 'n', 'N', 'null', 'NULL'), true)) {
|
316 |
+
$value = $this->_doLiteralBlock($value,$indent);
|
317 |
+
}
|
318 |
+
if (trim ($value) != $value)
|
319 |
+
$value = $this->_doLiteralBlock($value,$indent);
|
320 |
+
|
321 |
+
if (is_bool($value)) {
|
322 |
+
$value = ($value) ? "true" : "false";
|
323 |
+
}
|
324 |
+
|
325 |
+
if ($value === null) $value = 'null';
|
326 |
+
if ($value === "'" . self::REMPTY . "'") $value = null;
|
327 |
+
|
328 |
+
$spaces = str_repeat(' ',$indent);
|
329 |
+
|
330 |
+
//if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {
|
331 |
+
if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) {
|
332 |
+
// It's a sequence
|
333 |
+
$string = $spaces.'- '.$value."\n";
|
334 |
+
} else {
|
335 |
+
// if ($first_key===0) throw new Exception('Keys are all screwy. The first one was zero, now it\'s "'. $key .'"');
|
336 |
+
// It's mapped
|
337 |
+
if (strpos($key, ":") !== false || strpos($key, "#") !== false) { $key = '"' . $key . '"'; }
|
338 |
+
$string = rtrim ($spaces.$key.': '.$value)."\n";
|
339 |
+
}
|
340 |
+
return $string;
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* Creates a literal block for dumping
|
345 |
+
* @access private
|
346 |
+
* @return string
|
347 |
+
* @param $value
|
348 |
+
* @param $indent int The value of the indent
|
349 |
+
*/
|
350 |
+
private function _doLiteralBlock($value,$indent) {
|
351 |
+
if ($value === "\n") return '\n';
|
352 |
+
if (strpos($value, "\n") === false && strpos($value, "'") === false) {
|
353 |
+
return sprintf ("'%s'", $value);
|
354 |
+
}
|
355 |
+
if (strpos($value, "\n") === false && strpos($value, '"') === false) {
|
356 |
+
return sprintf ('"%s"', $value);
|
357 |
+
}
|
358 |
+
$exploded = explode("\n",$value);
|
359 |
+
$newValue = '|';
|
360 |
+
$indent += $this->_dumpIndent;
|
361 |
+
$spaces = str_repeat(' ',$indent);
|
362 |
+
foreach ($exploded as $line) {
|
363 |
+
$newValue .= "\n" . $spaces . ($line);
|
364 |
+
}
|
365 |
+
return $newValue;
|
366 |
+
}
|
367 |
+
|
368 |
+
/**
|
369 |
+
* Folds a string of text, if necessary
|
370 |
+
* @access private
|
371 |
+
* @return string
|
372 |
+
* @param $value The string you wish to fold
|
373 |
+
*/
|
374 |
+
private function _doFolding($value,$indent) {
|
375 |
+
// Don't do anything if wordwrap is set to 0
|
376 |
+
|
377 |
+
if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) {
|
378 |
+
$indent += $this->_dumpIndent;
|
379 |
+
$indent = str_repeat(' ',$indent);
|
380 |
+
$wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
|
381 |
+
$value = ">\n".$indent.$wrapped;
|
382 |
+
} else {
|
383 |
+
if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY)
|
384 |
+
$value = '"' . $value . '"';
|
385 |
+
}
|
386 |
+
|
387 |
+
|
388 |
+
return $value;
|
389 |
+
}
|
390 |
+
|
391 |
+
// LOADING FUNCTIONS
|
392 |
+
|
393 |
+
private function __load($input) {
|
394 |
+
$Source = $this->loadFromSource($input);
|
395 |
+
return $this->loadWithSource($Source);
|
396 |
+
}
|
397 |
+
|
398 |
+
private function __loadString($input) {
|
399 |
+
$Source = $this->loadFromString($input);
|
400 |
+
return $this->loadWithSource($Source);
|
401 |
+
}
|
402 |
+
|
403 |
+
private function loadWithSource($Source) {
|
404 |
+
if (empty ($Source)) return array();
|
405 |
+
if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) {
|
406 |
+
$array = syck_load (implode ('', $Source));
|
407 |
+
return is_array($array) ? $array : array();
|
408 |
+
}
|
409 |
+
|
410 |
+
$this->path = array();
|
411 |
+
$this->result = array();
|
412 |
+
|
413 |
+
$cnt = count($Source);
|
414 |
+
for ($i = 0; $i < $cnt; $i++) {
|
415 |
+
$line = $Source[$i];
|
416 |
+
|
417 |
+
$this->indent = strlen($line) - strlen(ltrim($line));
|
418 |
+
$tempPath = $this->getParentPathByIndent($this->indent);
|
419 |
+
$line = self::stripIndent($line, $this->indent);
|
420 |
+
if (self::isComment($line)) continue;
|
421 |
+
if (self::isEmpty($line)) continue;
|
422 |
+
$this->path = $tempPath;
|
423 |
+
|
424 |
+
$literalBlockStyle = self::startsLiteralBlock($line);
|
425 |
+
if ($literalBlockStyle) {
|
426 |
+
$line = rtrim ($line, $literalBlockStyle . " \n");
|
427 |
+
$literalBlock = '';
|
428 |
+
$line .= $this->LiteralPlaceHolder;
|
429 |
+
$literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1]));
|
430 |
+
while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) {
|
431 |
+
$literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent);
|
432 |
+
}
|
433 |
+
$i--;
|
434 |
+
}
|
435 |
+
|
436 |
+
while (++$i < $cnt && self::greedilyNeedNextLine($line)) {
|
437 |
+
$line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t");
|
438 |
+
}
|
439 |
+
$i--;
|
440 |
+
|
441 |
+
|
442 |
+
|
443 |
+
if (strpos ($line, '#')) {
|
444 |
+
if (strpos ($line, '"') === false && strpos ($line, "'") === false)
|
445 |
+
$line = preg_replace('/\s+#(.+)$/','',$line);
|
446 |
+
}
|
447 |
+
|
448 |
+
$lineArray = $this->_parseLine($line);
|
449 |
+
|
450 |
+
if ($literalBlockStyle)
|
451 |
+
$lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock);
|
452 |
+
|
453 |
+
$this->addArray($lineArray, $this->indent);
|
454 |
+
|
455 |
+
foreach ($this->delayedPath as $indent => $delayedPath)
|
456 |
+
$this->path[$indent] = $delayedPath;
|
457 |
+
|
458 |
+
$this->delayedPath = array();
|
459 |
+
|
460 |
+
}
|
461 |
+
return $this->result;
|
462 |
+
}
|
463 |
+
|
464 |
+
private function loadFromSource ($input) {
|
465 |
+
if (!empty($input) && strpos($input, "\n") === false && file_exists($input))
|
466 |
+
return file($input);
|
467 |
+
|
468 |
+
return $this->loadFromString($input);
|
469 |
+
}
|
470 |
+
|
471 |
+
private function loadFromString ($input) {
|
472 |
+
$lines = explode("\n",$input);
|
473 |
+
foreach ($lines as $k => $_) {
|
474 |
+
$lines[$k] = rtrim ($_, "\r");
|
475 |
+
}
|
476 |
+
return $lines;
|
477 |
+
}
|
478 |
+
|
479 |
+
/**
|
480 |
+
* Parses YAML code and returns an array for a node
|
481 |
+
* @access private
|
482 |
+
* @return array
|
483 |
+
* @param string $line A line from the YAML file
|
484 |
+
*/
|
485 |
+
private function _parseLine($line) {
|
486 |
+
if (!$line) return array();
|
487 |
+
$line = trim($line);
|
488 |
+
if (!$line) return array();
|
489 |
+
|
490 |
+
$array = array();
|
491 |
+
|
492 |
+
$group = $this->nodeContainsGroup($line);
|
493 |
+
if ($group) {
|
494 |
+
$this->addGroup($line, $group);
|
495 |
+
$line = $this->stripGroup ($line, $group);
|
496 |
+
}
|
497 |
+
|
498 |
+
if ($this->startsMappedSequence($line))
|
499 |
+
return $this->returnMappedSequence($line);
|
500 |
+
|
501 |
+
if ($this->startsMappedValue($line))
|
502 |
+
return $this->returnMappedValue($line);
|
503 |
+
|
504 |
+
if ($this->isArrayElement($line))
|
505 |
+
return $this->returnArrayElement($line);
|
506 |
+
|
507 |
+
if ($this->isPlainArray($line))
|
508 |
+
return $this->returnPlainArray($line);
|
509 |
+
|
510 |
+
|
511 |
+
return $this->returnKeyValuePair($line);
|
512 |
+
|
513 |
+
}
|
514 |
+
|
515 |
+
/**
|
516 |
+
* Finds the type of the passed value, returns the value as the new type.
|
517 |
+
* @access private
|
518 |
+
* @param string $value
|
519 |
+
* @return mixed
|
520 |
+
*/
|
521 |
+
private function _toType($value) {
|
522 |
+
if ($value === '') return null;
|
523 |
+
$first_character = $value[0];
|
524 |
+
$last_character = substr($value, -1, 1);
|
525 |
+
|
526 |
+
$is_quoted = false;
|
527 |
+
do {
|
528 |
+
if (!$value) break;
|
529 |
+
if ($first_character != '"' && $first_character != "'") break;
|
530 |
+
if ($last_character != '"' && $last_character != "'") break;
|
531 |
+
$is_quoted = true;
|
532 |
+
} while (0);
|
533 |
+
|
534 |
+
if ($is_quoted)
|
535 |
+
return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\''));
|
536 |
+
|
537 |
+
if (strpos($value, ' #') !== false && !$is_quoted)
|
538 |
+
$value = preg_replace('/\s+#(.+)$/','',$value);
|
539 |
+
|
540 |
+
if (!$is_quoted) $value = str_replace('\n', "\n", $value);
|
541 |
+
|
542 |
+
if ($first_character == '[' && $last_character == ']') {
|
543 |
+
// Take out strings sequences and mappings
|
544 |
+
$innerValue = trim(substr ($value, 1, -1));
|
545 |
+
if ($innerValue === '') return array();
|
546 |
+
$explode = $this->_inlineEscape($innerValue);
|
547 |
+
// Propagate value array
|
548 |
+
$value = array();
|
549 |
+
foreach ($explode as $v) {
|
550 |
+
$value[] = $this->_toType($v);
|
551 |
+
}
|
552 |
+
return $value;
|
553 |
+
}
|
554 |
+
|
555 |
+
if (strpos($value,': ')!==false && $first_character != '{') {
|
556 |
+
$array = explode(': ',$value);
|
557 |
+
$key = trim($array[0]);
|
558 |
+
array_shift($array);
|
559 |
+
$value = trim(implode(': ',$array));
|
560 |
+
$value = $this->_toType($value);
|
561 |
+
return array($key => $value);
|
562 |
+
}
|
563 |
+
|
564 |
+
if ($first_character == '{' && $last_character == '}') {
|
565 |
+
$innerValue = trim(substr ($value, 1, -1));
|
566 |
+
if ($innerValue === '') return array();
|
567 |
+
// Inline Mapping
|
568 |
+
// Take out strings sequences and mappings
|
569 |
+
$explode = $this->_inlineEscape($innerValue);
|
570 |
+
// Propagate value array
|
571 |
+
$array = array();
|
572 |
+
foreach ($explode as $v) {
|
573 |
+
$SubArr = $this->_toType($v);
|
574 |
+
if (empty($SubArr)) continue;
|
575 |
+
if (is_array ($SubArr)) {
|
576 |
+
$array[key($SubArr)] = $SubArr[key($SubArr)]; continue;
|
577 |
+
}
|
578 |
+
$array[] = $SubArr;
|
579 |
+
}
|
580 |
+
return $array;
|
581 |
+
}
|
582 |
+
|
583 |
+
if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') {
|
584 |
+
return null;
|
585 |
+
}
|
586 |
+
|
587 |
+
if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){
|
588 |
+
$intvalue = (int)$value;
|
589 |
+
if ($intvalue != PHP_INT_MAX)
|
590 |
+
$value = $intvalue;
|
591 |
+
return $value;
|
592 |
+
}
|
593 |
+
|
594 |
+
if (in_array($value,
|
595 |
+
array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) {
|
596 |
+
return true;
|
597 |
+
}
|
598 |
+
|
599 |
+
if (in_array(strtolower($value),
|
600 |
+
array('false', 'off', '-', 'no', 'n'))) {
|
601 |
+
return false;
|
602 |
+
}
|
603 |
+
|
604 |
+
if (is_numeric($value)) {
|
605 |
+
if ($value === '0') return 0;
|
606 |
+
if (rtrim ($value, 0) === $value)
|
607 |
+
$value = (float)$value;
|
608 |
+
return $value;
|
609 |
+
}
|
610 |
+
|
611 |
+
return $value;
|
612 |
+
}
|
613 |
+
|
614 |
+
/**
|
615 |
+
* Used in inlines to check for more inlines or quoted strings
|
616 |
+
* @access private
|
617 |
+
* @return array
|
618 |
+
*/
|
619 |
+
private function _inlineEscape($inline) {
|
620 |
+
// There's gotta be a cleaner way to do this...
|
621 |
+
// While pure sequences seem to be nesting just fine,
|
622 |
+
// pure mappings and mappings with sequences inside can't go very
|
623 |
+
// deep. This needs to be fixed.
|
624 |
+
|
625 |
+
$seqs = array();
|
626 |
+
$maps = array();
|
627 |
+
$saved_strings = array();
|
628 |
+
|
629 |
+
// Check for strings
|
630 |
+
$regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
|
631 |
+
if (preg_match_all($regex,$inline,$strings)) {
|
632 |
+
$saved_strings = $strings[0];
|
633 |
+
$inline = preg_replace($regex,'YAMLString',$inline);
|
634 |
+
}
|
635 |
+
unset($regex);
|
636 |
+
|
637 |
+
$i = 0;
|
638 |
+
do {
|
639 |
+
|
640 |
+
// Check for sequences
|
641 |
+
while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) {
|
642 |
+
$seqs[] = $matchseqs[0];
|
643 |
+
$inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1);
|
644 |
+
}
|
645 |
+
|
646 |
+
// Check for mappings
|
647 |
+
while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) {
|
648 |
+
$maps[] = $matchmaps[0];
|
649 |
+
$inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1);
|
650 |
+
}
|
651 |
+
|
652 |
+
if ($i++ >= 10) break;
|
653 |
+
|
654 |
+
} while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false);
|
655 |
+
|
656 |
+
$explode = explode(', ',$inline);
|
657 |
+
$stringi = 0; $i = 0;
|
658 |
+
|
659 |
+
while (1) {
|
660 |
+
|
661 |
+
// Re-add the sequences
|
662 |
+
if (!empty($seqs)) {
|
663 |
+
foreach ($explode as $key => $value) {
|
664 |
+
if (strpos($value,'YAMLSeq') !== false) {
|
665 |
+
foreach ($seqs as $seqk => $seq) {
|
666 |
+
$explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value);
|
667 |
+
$value = $explode[$key];
|
668 |
+
}
|
669 |
+
}
|
670 |
+
}
|
671 |
+
}
|
672 |
+
|
673 |
+
// Re-add the mappings
|
674 |
+
if (!empty($maps)) {
|
675 |
+
foreach ($explode as $key => $value) {
|
676 |
+
if (strpos($value,'YAMLMap') !== false) {
|
677 |
+
foreach ($maps as $mapk => $map) {
|
678 |
+
$explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value);
|
679 |
+
$value = $explode[$key];
|
680 |
+
}
|
681 |
+
}
|
682 |
+
}
|
683 |
+
}
|
684 |
+
|
685 |
+
|
686 |
+
// Re-add the strings
|
687 |
+
if (!empty($saved_strings)) {
|
688 |
+
foreach ($explode as $key => $value) {
|
689 |
+
while (strpos($value,'YAMLString') !== false) {
|
690 |
+
$explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1);
|
691 |
+
unset($saved_strings[$stringi]);
|
692 |
+
++$stringi;
|
693 |
+
$value = $explode[$key];
|
694 |
+
}
|
695 |
+
}
|
696 |
+
}
|
697 |
+
|
698 |
+
$finished = true;
|
699 |
+
foreach ($explode as $key => $value) {
|
700 |
+
if (strpos($value,'YAMLSeq') !== false) {
|
701 |
+
$finished = false; break;
|
702 |
+
}
|
703 |
+
if (strpos($value,'YAMLMap') !== false) {
|
704 |
+
$finished = false; break;
|
705 |
+
}
|
706 |
+
if (strpos($value,'YAMLString') !== false) {
|
707 |
+
$finished = false; break;
|
708 |
+
}
|
709 |
+
}
|
710 |
+
if ($finished) break;
|
711 |
+
|
712 |
+
$i++;
|
713 |
+
if ($i > 10)
|
714 |
+
break; // Prevent infinite loops.
|
715 |
+
}
|
716 |
+
|
717 |
+
return $explode;
|
718 |
+
}
|
719 |
+
|
720 |
+
private function literalBlockContinues ($line, $lineIndent) {
|
721 |
+
if (!trim($line)) return true;
|
722 |
+
if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true;
|
723 |
+
return false;
|
724 |
+
}
|
725 |
+
|
726 |
+
private function referenceContentsByAlias ($alias) {
|
727 |
+
do {
|
728 |
+
if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; }
|
729 |
+
$groupPath = $this->SavedGroups[$alias];
|
730 |
+
$value = $this->result;
|
731 |
+
foreach ($groupPath as $k) {
|
732 |
+
$value = $value[$k];
|
733 |
+
}
|
734 |
+
} while (false);
|
735 |
+
return $value;
|
736 |
+
}
|
737 |
+
|
738 |
+
private function addArrayInline ($array, $indent) {
|
739 |
+
$CommonGroupPath = $this->path;
|
740 |
+
if (empty ($array)) return false;
|
741 |
+
|
742 |
+
foreach ($array as $k => $_) {
|
743 |
+
$this->addArray(array($k => $_), $indent);
|
744 |
+
$this->path = $CommonGroupPath;
|
745 |
+
}
|
746 |
+
return true;
|
747 |
+
}
|
748 |
+
|
749 |
+
private function addArray ($incoming_data, $incoming_indent) {
|
750 |
+
|
751 |
+
// print_r ($incoming_data);
|
752 |
+
|
753 |
+
if (count ($incoming_data) > 1)
|
754 |
+
return $this->addArrayInline ($incoming_data, $incoming_indent);
|
755 |
+
|
756 |
+
$key = key ($incoming_data);
|
757 |
+
$value = isset($incoming_data[$key]) ? $incoming_data[$key] : null;
|
758 |
+
if ($key === '__!YAMLZero') $key = '0';
|
759 |
+
|
760 |
+
if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values.
|
761 |
+
if ($key || $key === '' || $key === '0') {
|
762 |
+
$this->result[$key] = $value;
|
763 |
+
} else {
|
764 |
+
$this->result[] = $value; end ($this->result); $key = key ($this->result);
|
765 |
+
}
|
766 |
+
$this->path[$incoming_indent] = $key;
|
767 |
+
return;
|
768 |
+
}
|
769 |
+
|
770 |
+
|
771 |
+
|
772 |
+
$history = array();
|
773 |
+
// Unfolding inner array tree.
|
774 |
+
$history[] = $_arr = $this->result;
|
775 |
+
foreach ($this->path as $k) {
|
776 |
+
$history[] = $_arr = $_arr[$k];
|
777 |
+
}
|
778 |
+
|
779 |
+
if ($this->_containsGroupAlias) {
|
780 |
+
$value = $this->referenceContentsByAlias($this->_containsGroupAlias);
|
781 |
+
$this->_containsGroupAlias = false;
|
782 |
+
}
|
783 |
+
|
784 |
+
|
785 |
+
// Adding string or numeric key to the innermost level or $this->arr.
|
786 |
+
if (is_string($key) && $key == '<<') {
|
787 |
+
if (!is_array ($_arr)) { $_arr = array (); }
|
788 |
+
|
789 |
+
$_arr = array_merge ($_arr, $value);
|
790 |
+
} else if ($key || $key === '' || $key === '0') {
|
791 |
+
if (!is_array ($_arr))
|
792 |
+
$_arr = array ($key=>$value);
|
793 |
+
else
|
794 |
+
$_arr[$key] = $value;
|
795 |
+
} else {
|
796 |
+
if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; }
|
797 |
+
else { $_arr[] = $value; end ($_arr); $key = key ($_arr); }
|
798 |
+
}
|
799 |
+
|
800 |
+
$reverse_path = array_reverse($this->path);
|
801 |
+
$reverse_history = array_reverse ($history);
|
802 |
+
$reverse_history[0] = $_arr;
|
803 |
+
$cnt = count($reverse_history) - 1;
|
804 |
+
for ($i = 0; $i < $cnt; $i++) {
|
805 |
+
$reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i];
|
806 |
+
}
|
807 |
+
$this->result = $reverse_history[$cnt];
|
808 |
+
|
809 |
+
$this->path[$incoming_indent] = $key;
|
810 |
+
|
811 |
+
if ($this->_containsGroupAnchor) {
|
812 |
+
$this->SavedGroups[$this->_containsGroupAnchor] = $this->path;
|
813 |
+
if (is_array ($value)) {
|
814 |
+
$k = key ($value);
|
815 |
+
if (!is_int ($k)) {
|
816 |
+
$this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k;
|
817 |
+
}
|
818 |
+
}
|
819 |
+
$this->_containsGroupAnchor = false;
|
820 |
+
}
|
821 |
+
|
822 |
+
}
|
823 |
+
|
824 |
+
private static function startsLiteralBlock ($line) {
|
825 |
+
$lastChar = substr (trim($line), -1);
|
826 |
+
if ($lastChar != '>' && $lastChar != '|') return false;
|
827 |
+
if ($lastChar == '|') return $lastChar;
|
828 |
+
// HTML tags should not be counted as literal blocks.
|
829 |
+
if (preg_match ('#<.*?>$#', $line)) return false;
|
830 |
+
return $lastChar;
|
831 |
+
}
|
832 |
+
|
833 |
+
private static function greedilyNeedNextLine($line) {
|
834 |
+
$line = trim ($line);
|
835 |
+
if (!strlen($line)) return false;
|
836 |
+
if (substr ($line, -1, 1) == ']') return false;
|
837 |
+
if ($line[0] == '[') return true;
|
838 |
+
if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true;
|
839 |
+
return false;
|
840 |
+
}
|
841 |
+
|
842 |
+
private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) {
|
843 |
+
$line = self::stripIndent($line, $indent);
|
844 |
+
if ($literalBlockStyle !== '|') {
|
845 |
+
$line = self::stripIndent($line);
|
846 |
+
}
|
847 |
+
$line = rtrim ($line, "\r\n\t ") . "\n";
|
848 |
+
if ($literalBlockStyle == '|') {
|
849 |
+
return $literalBlock . $line;
|
850 |
+
}
|
851 |
+
if (strlen($line) == 0)
|
852 |
+
return rtrim($literalBlock, ' ') . "\n";
|
853 |
+
if ($line == "\n" && $literalBlockStyle == '>') {
|
854 |
+
return rtrim ($literalBlock, " \t") . "\n";
|
855 |
+
}
|
856 |
+
if ($line != "\n")
|
857 |
+
$line = trim ($line, "\r\n ") . " ";
|
858 |
+
return $literalBlock . $line;
|
859 |
+
}
|
860 |
+
|
861 |
+
function revertLiteralPlaceHolder ($lineArray, $literalBlock) {
|
862 |
+
foreach ($lineArray as $k => $_) {
|
863 |
+
if (is_array($_))
|
864 |
+
$lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock);
|
865 |
+
else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder)
|
866 |
+
$lineArray[$k] = rtrim ($literalBlock, " \r\n");
|
867 |
+
}
|
868 |
+
return $lineArray;
|
869 |
+
}
|
870 |
+
|
871 |
+
private static function stripIndent ($line, $indent = -1) {
|
872 |
+
if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line));
|
873 |
+
return substr ($line, $indent);
|
874 |
+
}
|
875 |
+
|
876 |
+
private function getParentPathByIndent ($indent) {
|
877 |
+
if ($indent == 0) return array();
|
878 |
+
$linePath = $this->path;
|
879 |
+
do {
|
880 |
+
end($linePath); $lastIndentInParentPath = key($linePath);
|
881 |
+
if ($indent <= $lastIndentInParentPath) array_pop ($linePath);
|
882 |
+
} while ($indent <= $lastIndentInParentPath);
|
883 |
+
return $linePath;
|
884 |
+
}
|
885 |
+
|
886 |
+
|
887 |
+
private function clearBiggerPathValues ($indent) {
|
888 |
+
|
889 |
+
|
890 |
+
if ($indent == 0) $this->path = array();
|
891 |
+
if (empty ($this->path)) return true;
|
892 |
+
|
893 |
+
foreach ($this->path as $k => $_) {
|
894 |
+
if ($k > $indent) unset ($this->path[$k]);
|
895 |
+
}
|
896 |
+
|
897 |
+
return true;
|
898 |
+
}
|
899 |
+
|
900 |
+
|
901 |
+
private static function isComment ($line) {
|
902 |
+
if (!$line) return false;
|
903 |
+
if ($line[0] == '#') return true;
|
904 |
+
if (trim($line, " \r\n\t") == '---') return true;
|
905 |
+
return false;
|
906 |
+
}
|
907 |
+
|
908 |
+
private static function isEmpty ($line) {
|
909 |
+
return (trim ($line) === '');
|
910 |
+
}
|
911 |
+
|
912 |
+
|
913 |
+
private function isArrayElement ($line) {
|
914 |
+
if (!$line) return false;
|
915 |
+
if ($line[0] != '-') return false;
|
916 |
+
if (strlen ($line) > 3)
|
917 |
+
if (substr($line,0,3) == '---') return false;
|
918 |
+
|
919 |
+
return true;
|
920 |
+
}
|
921 |
+
|
922 |
+
private function isHashElement ($line) {
|
923 |
+
return strpos($line, ':');
|
924 |
+
}
|
925 |
+
|
926 |
+
private function isLiteral ($line) {
|
927 |
+
if ($this->isArrayElement($line)) return false;
|
928 |
+
if ($this->isHashElement($line)) return false;
|
929 |
+
return true;
|
930 |
+
}
|
931 |
+
|
932 |
+
|
933 |
+
private static function unquote ($value) {
|
934 |
+
if (!$value) return $value;
|
935 |
+
if (!is_string($value)) return $value;
|
936 |
+
if ($value[0] == '\'') return trim ($value, '\'');
|
937 |
+
if ($value[0] == '"') return trim ($value, '"');
|
938 |
+
return $value;
|
939 |
+
}
|
940 |
+
|
941 |
+
private function startsMappedSequence ($line) {
|
942 |
+
return ($line[0] == '-' && substr ($line, -1, 1) == ':');
|
943 |
+
}
|
944 |
+
|
945 |
+
private function returnMappedSequence ($line) {
|
946 |
+
$array = array();
|
947 |
+
$key = self::unquote(trim(substr($line,1,-1)));
|
948 |
+
$array[$key] = array();
|
949 |
+
$this->delayedPath = array(strpos ($line, $key) + $this->indent => $key);
|
950 |
+
return array($array);
|
951 |
+
}
|
952 |
+
|
953 |
+
private function returnMappedValue ($line) {
|
954 |
+
$array = array();
|
955 |
+
$key = self::unquote (trim(substr($line,0,-1)));
|
956 |
+
$array[$key] = '';
|
957 |
+
return $array;
|
958 |
+
}
|
959 |
+
|
960 |
+
private function startsMappedValue ($line) {
|
961 |
+
return (substr ($line, -1, 1) == ':');
|
962 |
+
}
|
963 |
+
|
964 |
+
private function isPlainArray ($line) {
|
965 |
+
return ($line[0] == '[' && substr ($line, -1, 1) == ']');
|
966 |
+
}
|
967 |
+
|
968 |
+
private function returnPlainArray ($line) {
|
969 |
+
return $this->_toType($line);
|
970 |
+
}
|
971 |
+
|
972 |
+
private function returnKeyValuePair ($line) {
|
973 |
+
$array = array();
|
974 |
+
$key = '';
|
975 |
+
if (strpos ($line, ':')) {
|
976 |
+
// It's a key/value pair most likely
|
977 |
+
// If the key is in double quotes pull it out
|
978 |
+
if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) {
|
979 |
+
$value = trim(str_replace($matches[1],'',$line));
|
980 |
+
$key = $matches[2];
|
981 |
+
} else {
|
982 |
+
// Do some guesswork as to the key and the value
|
983 |
+
$explode = explode(':',$line);
|
984 |
+
$key = trim($explode[0]);
|
985 |
+
array_shift($explode);
|
986 |
+
$value = trim(implode(':',$explode));
|
987 |
+
}
|
988 |
+
// Set the type of the value. Int, string, etc
|
989 |
+
$value = $this->_toType($value);
|
990 |
+
if ($key === '0') $key = '__!YAMLZero';
|
991 |
+
$array[$key] = $value;
|
992 |
+
} else {
|
993 |
+
$array = array ($line);
|
994 |
+
}
|
995 |
+
return $array;
|
996 |
+
|
997 |
+
}
|
998 |
+
|
999 |
+
|
1000 |
+
private function returnArrayElement ($line) {
|
1001 |
+
if (strlen($line) <= 1) return array(array()); // Weird %)
|
1002 |
+
$array = array();
|
1003 |
+
$value = trim(substr($line,1));
|
1004 |
+
$value = $this->_toType($value);
|
1005 |
+
$array[] = $value;
|
1006 |
+
return $array;
|
1007 |
+
}
|
1008 |
+
|
1009 |
+
|
1010 |
+
private function nodeContainsGroup ($line) {
|
1011 |
+
$symbolsForReference = 'A-z0-9_\-';
|
1012 |
+
if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-)
|
1013 |
+
if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
|
1014 |
+
if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
|
1015 |
+
if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1];
|
1016 |
+
if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1];
|
1017 |
+
if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1];
|
1018 |
+
return false;
|
1019 |
+
|
1020 |
+
}
|
1021 |
+
|
1022 |
+
private function addGroup ($line, $group) {
|
1023 |
+
if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1);
|
1024 |
+
if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1);
|
1025 |
+
//print_r ($this->path);
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
private function stripGroup ($line, $group) {
|
1029 |
+
$line = trim(str_replace($group, '', $line));
|
1030 |
+
return $line;
|
1031 |
+
}
|
1032 |
+
}
|
1033 |
+
|
1034 |
+
// Enable use of Spyc from command line
|
1035 |
+
// The syntax is the following: php spyc.php spyc.yaml
|
1036 |
+
|
1037 |
+
define ('SPYC_FROM_COMMAND_LINE', false);
|
1038 |
+
|
1039 |
+
do {
|
1040 |
+
if (!SPYC_FROM_COMMAND_LINE) break;
|
1041 |
+
if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break;
|
1042 |
+
if (empty ($_SERVER['PHP_SELF']) || $_SERVER['PHP_SELF'] != 'spyc.php') break;
|
1043 |
+
$file = $argv[1];
|
1044 |
+
printf ("Spyc loading file: %s\n", $file);
|
1045 |
+
print_r (spyc_load_file ($file));
|
1046 |
+
} while (0);
|
includes/admin/uaparser/lib/spyc-0.5/spyc.yaml
ADDED
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#
|
2 |
+
# S P Y C
|
3 |
+
# a simple php yaml class
|
4 |
+
#
|
5 |
+
# authors: [vlad andersen (vlad.andersen@gmail.com), chris wanstrath (chris@ozmm.org)]
|
6 |
+
# websites: [http://www.yaml.org, http://spyc.sourceforge.net/]
|
7 |
+
# license: [MIT License, http://www.opensource.org/licenses/mit-license.php]
|
8 |
+
# copyright: (c) 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen
|
9 |
+
#
|
10 |
+
# spyc.yml - A file containing the YAML that Spyc understands.
|
11 |
+
|
12 |
+
---
|
13 |
+
|
14 |
+
# Mappings - with proper types
|
15 |
+
String: Anyone's name, really.
|
16 |
+
Int: 13
|
17 |
+
True: true
|
18 |
+
False: false
|
19 |
+
Zero: 0
|
20 |
+
Null: NULL
|
21 |
+
NotNull: 'null'
|
22 |
+
NotTrue: 'y'
|
23 |
+
NotBoolTrue: 'true'
|
24 |
+
NotInt: '5'
|
25 |
+
Float: 5.34
|
26 |
+
Negative: -90
|
27 |
+
SmallFloat: 0.7
|
28 |
+
NewLine: \n
|
29 |
+
|
30 |
+
# A sequence
|
31 |
+
- PHP Class
|
32 |
+
- Basic YAML Loader
|
33 |
+
- Very Basic YAML Dumper
|
34 |
+
|
35 |
+
# A sequence of a sequence
|
36 |
+
-
|
37 |
+
- YAML is so easy to learn.
|
38 |
+
- Your config files will never be the same.
|
39 |
+
|
40 |
+
# Sequence of mappings
|
41 |
+
-
|
42 |
+
cpu: 1.5ghz
|
43 |
+
ram: 1 gig
|
44 |
+
os : os x 10.4.1
|
45 |
+
|
46 |
+
# Mapped sequence
|
47 |
+
domains:
|
48 |
+
- yaml.org
|
49 |
+
- php.net
|
50 |
+
|
51 |
+
# A sequence like this.
|
52 |
+
- program: Adium
|
53 |
+
platform: OS X
|
54 |
+
type: Chat Client
|
55 |
+
|
56 |
+
# A folded block as a mapped value
|
57 |
+
no time: >
|
58 |
+
There isn't any time
|
59 |
+
for your tricks!
|
60 |
+
|
61 |
+
Do you understand?
|
62 |
+
|
63 |
+
# A literal block as a mapped value
|
64 |
+
some time: |
|
65 |
+
There is nothing but time
|
66 |
+
for your tricks.
|
67 |
+
|
68 |
+
# Crazy combinations
|
69 |
+
databases:
|
70 |
+
- name: spartan
|
71 |
+
notes:
|
72 |
+
- Needs to be backed up
|
73 |
+
- Needs to be normalized
|
74 |
+
type: mysql
|
75 |
+
|
76 |
+
# You can be a bit tricky
|
77 |
+
"if: you'd": like
|
78 |
+
|
79 |
+
# Inline sequences
|
80 |
+
- [One, Two, Three, Four]
|
81 |
+
|
82 |
+
# Nested Inline Sequences
|
83 |
+
- [One, [Two, And, Three], Four, Five]
|
84 |
+
|
85 |
+
# Nested Nested Inline Sequences
|
86 |
+
- [This, [Is, Getting, [Ridiculous, Guys]], Seriously, [Show, Mercy]]
|
87 |
+
|
88 |
+
# Inline mappings
|
89 |
+
- {name: chris, age: young, brand: lucky strike}
|
90 |
+
|
91 |
+
# Nested inline mappings
|
92 |
+
- {name: mark, age: older than chris, brand: [marlboro, lucky strike]}
|
93 |
+
|
94 |
+
# References -- they're shaky, but functional
|
95 |
+
dynamic languages: &DLANGS
|
96 |
+
- Perl
|
97 |
+
- Python
|
98 |
+
- PHP
|
99 |
+
- Ruby
|
100 |
+
compiled languages: &CLANGS
|
101 |
+
- C/C++
|
102 |
+
- Java
|
103 |
+
all languages:
|
104 |
+
- *DLANGS
|
105 |
+
- *CLANGS
|
106 |
+
|
107 |
+
# Added in .2.2: Escaped quotes
|
108 |
+
- you know, this shouldn't work. but it does.
|
109 |
+
- 'that''s my value.'
|
110 |
+
- 'again, that\'s my value.'
|
111 |
+
- "here's to \"quotes\", boss."
|
112 |
+
|
113 |
+
# added in .2.3
|
114 |
+
- {name: "Foo, Bar's", age: 20}
|
115 |
+
|
116 |
+
# Added in .2.4: bug [ 1418193 ] Quote Values in Nested Arrays
|
117 |
+
- [a, ['1', "2"], b]
|
118 |
+
|
119 |
+
# Added in .2.4: malformed YAML
|
120 |
+
all
|
121 |
+
javascripts: [dom1.js, dom.js]
|
122 |
+
|
123 |
+
# Added in .2
|
124 |
+
1040: Ooo, a numeric key! # And working comments? Wow! Colons in comments: a menace (0.3).
|
125 |
+
|
126 |
+
hash_1: Hash #and a comment
|
127 |
+
hash_2: "Hash #and a comment"
|
128 |
+
"hash#3": "Hash (#) can appear in key too"
|
129 |
+
|
130 |
+
float_test: 1.0
|
131 |
+
float_test_with_quotes: '1.0'
|
132 |
+
float_inverse_test: 001
|
133 |
+
|
134 |
+
a_really_large_number: 115792089237316195423570985008687907853269984665640564039457584007913129639936 # 2^256
|
135 |
+
|
136 |
+
int array: [ 1, 2, 3 ]
|
137 |
+
|
138 |
+
array on several lines:
|
139 |
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
140 |
+
10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ]
|
141 |
+
|
142 |
+
morelesskey: "<value>"
|
143 |
+
|
144 |
+
array_of_zero: [0]
|
145 |
+
sophisticated_array_of_zero: {rx: {tx: [0]} }
|
146 |
+
|
147 |
+
switches:
|
148 |
+
- { row: 0, col: 0, func: {tx: [0, 1]} }
|
149 |
+
|
150 |
+
empty_sequence: [ ]
|
151 |
+
empty_hash: { }
|
152 |
+
|
153 |
+
special_characters: "[{]]{{]]"
|
154 |
+
|
155 |
+
asterisks: "*"
|
156 |
+
|
157 |
+
empty_key:
|
158 |
+
:
|
159 |
+
key: value
|
160 |
+
|
161 |
+
trailing_colon: "foo:"
|
162 |
+
|
163 |
+
multiline_items:
|
164 |
+
- type: SomeItem
|
165 |
+
values: [blah, blah, blah,
|
166 |
+
blah]
|
167 |
+
ints: [2, 54, 12,
|
168 |
+
2143]
|
169 |
+
|
170 |
+
many_lines: |
|
171 |
+
A quick
|
172 |
+
fox
|
173 |
+
|
174 |
+
|
175 |
+
jumped
|
176 |
+
over
|
177 |
+
|
178 |
+
|
179 |
+
|
180 |
+
|
181 |
+
|
182 |
+
a lazy
|
183 |
+
|
184 |
+
|
185 |
+
|
186 |
+
dog
|
187 |
+
|
188 |
+
|
189 |
+
werte:
|
190 |
+
1: nummer 1
|
191 |
+
0: Stunde 0
|
192 |
+
|
193 |
+
noindent_records:
|
194 |
+
- record1: value1
|
195 |
+
- record2: value2
|
196 |
+
|
197 |
+
"a:1": [1000]
|
198 |
+
"a:2":
|
199 |
+
- 2000
|
200 |
+
|
201 |
+
# [Endloop]
|
202 |
+
endloop: |
|
203 |
+
Does this line in the end indeed make Spyc go to an infinite loop?
|
includes/admin/uaparser/lib/spyc-0.5/tests/DumpTest.php
ADDED
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once ("../spyc.php");
|
4 |
+
|
5 |
+
class DumpTest extends PHPUnit_Framework_TestCase {
|
6 |
+
|
7 |
+
private $files_to_test = array();
|
8 |
+
|
9 |
+
public function setUp() {
|
10 |
+
$this->files_to_test = array ('../spyc.yaml', 'failing1.yaml', 'indent_1.yaml', 'quotes.yaml');
|
11 |
+
}
|
12 |
+
|
13 |
+
public function testDump() {
|
14 |
+
foreach ($this->files_to_test as $file) {
|
15 |
+
$yaml = spyc_load(file_get_contents($file));
|
16 |
+
$dump = Spyc::YAMLDump ($yaml);
|
17 |
+
$yaml_after_dump = Spyc::YAMLLoad ($dump);
|
18 |
+
$this->assertEquals ($yaml, $yaml_after_dump);
|
19 |
+
}
|
20 |
+
}
|
21 |
+
|
22 |
+
public function testDumpWithQuotes() {
|
23 |
+
$Spyc = new Spyc();
|
24 |
+
$Spyc->setting_dump_force_quotes = true;
|
25 |
+
foreach ($this->files_to_test as $file) {
|
26 |
+
$yaml = $Spyc->load(file_get_contents($file));
|
27 |
+
$dump = $Spyc->dump ($yaml);
|
28 |
+
$yaml_after_dump = Spyc::YAMLLoad ($dump);
|
29 |
+
$this->assertEquals ($yaml, $yaml_after_dump);
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
public function testDumpArrays() {
|
34 |
+
$dump = Spyc::YAMLDump(array ('item1', 'item2', 'item3'));
|
35 |
+
$awaiting = "---\n- item1\n- item2\n- item3\n";
|
36 |
+
$this->assertEquals ($awaiting, $dump);
|
37 |
+
}
|
38 |
+
|
39 |
+
public function testNull() {
|
40 |
+
$dump = Spyc::YAMLDump(array('a' => 1, 'b' => null, 'c' => 3));
|
41 |
+
$awaiting = "---\na: 1\nb: null\nc: 3\n";
|
42 |
+
$this->assertEquals ($awaiting, $dump);
|
43 |
+
}
|
44 |
+
|
45 |
+
public function testNext() {
|
46 |
+
$array = array("aaa", "bbb", "ccc");
|
47 |
+
#set arrays internal pointer to next element
|
48 |
+
next($array);
|
49 |
+
$dump = Spyc::YAMLDump($array);
|
50 |
+
$awaiting = "---\n- aaa\n- bbb\n- ccc\n";
|
51 |
+
$this->assertEquals ($awaiting, $dump);
|
52 |
+
}
|
53 |
+
|
54 |
+
public function testDumpingMixedArrays() {
|
55 |
+
$array = array();
|
56 |
+
$array[] = 'Sequence item';
|
57 |
+
$array['The Key'] = 'Mapped value';
|
58 |
+
$array[] = array('A sequence','of a sequence');
|
59 |
+
$array[] = array('first' => 'A sequence','second' => 'of mapped values');
|
60 |
+
$array['Mapped'] = array('A sequence','which is mapped');
|
61 |
+
$array['A Note'] = 'What if your text is too long?';
|
62 |
+
$array['Another Note'] = 'If that is the case, the dumper will probably fold your text by using a block. Kinda like this.';
|
63 |
+
$array['The trick?'] = 'The trick is that we overrode the default indent, 2, to 4 and the default wordwrap, 40, to 60.';
|
64 |
+
$array['Old Dog'] = "And if you want\n to preserve line breaks, \ngo ahead!";
|
65 |
+
$array['key:withcolon'] = "Should support this to";
|
66 |
+
|
67 |
+
$yaml = Spyc::YAMLDump($array,4,60);
|
68 |
+
}
|
69 |
+
|
70 |
+
public function testMixed() {
|
71 |
+
$dump = Spyc::YAMLDump(array(0 => 1, 'b' => 2, 1 => 3));
|
72 |
+
$awaiting = "---\n0: 1\nb: 2\n1: 3\n";
|
73 |
+
$this->assertEquals ($awaiting, $dump);
|
74 |
+
}
|
75 |
+
|
76 |
+
public function testDumpNumerics() {
|
77 |
+
$dump = Spyc::YAMLDump(array ('404', '405', '500'));
|
78 |
+
$awaiting = "---\n- 404\n- 405\n- 500\n";
|
79 |
+
$this->assertEquals ($awaiting, $dump);
|
80 |
+
}
|
81 |
+
|
82 |
+
public function testDumpAsterisks() {
|
83 |
+
$dump = Spyc::YAMLDump(array ('*'));
|
84 |
+
$awaiting = "---\n- '*'\n";
|
85 |
+
$this->assertEquals ($awaiting, $dump);
|
86 |
+
}
|
87 |
+
|
88 |
+
public function testDumpAmpersands() {
|
89 |
+
$dump = Spyc::YAMLDump(array ('some' => '&foo'));
|
90 |
+
$awaiting = "---\nsome: '&foo'\n";
|
91 |
+
$this->assertEquals ($awaiting, $dump);
|
92 |
+
}
|
93 |
+
|
94 |
+
public function testDumpExclamations() {
|
95 |
+
$dump = Spyc::YAMLDump(array ('some' => '!foo'));
|
96 |
+
$awaiting = "---\nsome: '!foo'\n";
|
97 |
+
$this->assertEquals ($awaiting, $dump);
|
98 |
+
}
|
99 |
+
|
100 |
+
public function testDumpExclamations2() {
|
101 |
+
$dump = Spyc::YAMLDump(array ('some' => 'foo!'));
|
102 |
+
$awaiting = "---\nsome: foo!\n";
|
103 |
+
$this->assertEquals ($awaiting, $dump);
|
104 |
+
}
|
105 |
+
|
106 |
+
public function testDumpApostrophes() {
|
107 |
+
$dump = Spyc::YAMLDump(array ('some' => "'Biz' pimpt bedrijventerreinen"));
|
108 |
+
$awaiting = "---\nsome: \"'Biz' pimpt bedrijventerreinen\"\n";
|
109 |
+
$this->assertEquals ($awaiting, $dump);
|
110 |
+
}
|
111 |
+
|
112 |
+
public function testDumpNumericHashes() {
|
113 |
+
$dump = Spyc::YAMLDump(array ("titel"=> array("0" => "", 1 => "Dr.", 5 => "Prof.", 6 => "Prof. Dr.")));
|
114 |
+
$awaiting = "---\ntitel:\n 0:\n 1: Dr.\n 5: Prof.\n 6: Prof. Dr.\n";
|
115 |
+
$this->assertEquals ($awaiting, $dump);
|
116 |
+
}
|
117 |
+
|
118 |
+
public function testEmpty() {
|
119 |
+
$dump = Spyc::YAMLDump(array("foo" => array()));
|
120 |
+
$awaiting = "---\nfoo: [ ]\n";
|
121 |
+
$this->assertEquals ($awaiting, $dump);
|
122 |
+
}
|
123 |
+
|
124 |
+
public function testHashesInKeys() {
|
125 |
+
$dump = Spyc::YAMLDump(array ('#color' => '#ffffff'));
|
126 |
+
$awaiting = "---\n\"#color\": '#ffffff'\n";
|
127 |
+
$this->assertEquals ($awaiting, $dump);
|
128 |
+
}
|
129 |
+
|
130 |
+
}
|
includes/admin/uaparser/lib/spyc-0.5/tests/IndentTest.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once ("../spyc.php");
|
4 |
+
|
5 |
+
class IndentTest extends PHPUnit_Framework_TestCase {
|
6 |
+
|
7 |
+
protected $Y;
|
8 |
+
|
9 |
+
protected function setUp() {
|
10 |
+
$this->Y = Spyc::YAMLLoad("indent_1.yaml");
|
11 |
+
}
|
12 |
+
|
13 |
+
public function testIndent_1() {
|
14 |
+
$this->assertEquals (array ('child_1' => 2, 'child_2' => 0, 'child_3' => 1), $this->Y['root']);
|
15 |
+
}
|
16 |
+
|
17 |
+
public function testIndent_2() {
|
18 |
+
$this->assertEquals (array ('child_1' => 1, 'child_2' => 2), $this->Y['root2']);
|
19 |
+
}
|
20 |
+
|
21 |
+
public function testIndent_3() {
|
22 |
+
$this->assertEquals (array (array ('resolutions' => array (1024 => 768, 1920 => 1200), 'producer' => 'Nec')), $this->Y['display']);
|
23 |
+
}
|
24 |
+
|
25 |
+
public function testIndent_4() {
|
26 |
+
$this->assertEquals (array (
|
27 |
+
array ('resolutions' => array (1024 => 768)),
|
28 |
+
array ('resolutions' => array (1920 => 1200)),
|
29 |
+
), $this->Y['displays']);
|
30 |
+
}
|
31 |
+
|
32 |
+
public function testIndent_5() {
|
33 |
+
$this->assertEquals (array (array (
|
34 |
+
'row' => 0,
|
35 |
+
'col' => 0,
|
36 |
+
'headsets_affected' => array (
|
37 |
+
array (
|
38 |
+
'ports' => array (0),
|
39 |
+
'side' => 'left',
|
40 |
+
)
|
41 |
+
),
|
42 |
+
'switch_function' => array (
|
43 |
+
'ics_ptt' => true
|
44 |
+
)
|
45 |
+
)), $this->Y['nested_hashes_and_seqs']);
|
46 |
+
}
|
47 |
+
|
48 |
+
public function testIndent_6() {
|
49 |
+
$this->assertEquals (array (
|
50 |
+
'h' => array (
|
51 |
+
array ('a' => 'b', 'a1' => 'b1'),
|
52 |
+
array ('c' => 'd')
|
53 |
+
)
|
54 |
+
), $this->Y['easier_nest']);
|
55 |
+
}
|
56 |
+
|
57 |
+
public function testIndent_space() {
|
58 |
+
$this->assertEquals ("By four\n spaces", $this->Y['one_space']);
|
59 |
+
}
|
60 |
+
|
61 |
+
public function testListAndComment() {
|
62 |
+
$this->assertEquals (array ('one', 'two', 'three'), $this->Y['list_and_comment']);
|
63 |
+
}
|
64 |
+
|
65 |
+
}
|
includes/admin/uaparser/lib/spyc-0.5/tests/ParseTest.php
ADDED
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once 'PHPUnit/Framework.php';
|
4 |
+
require_once ("../spyc.php");
|
5 |
+
|
6 |
+
class ParseTest extends PHPUnit_Framework_TestCase {
|
7 |
+
|
8 |
+
protected $yaml;
|
9 |
+
|
10 |
+
protected function setUp() {
|
11 |
+
$this->yaml = spyc_load_file('../spyc.yaml');
|
12 |
+
}
|
13 |
+
|
14 |
+
public function testMergeHashKeys() {
|
15 |
+
$Expected = array (
|
16 |
+
array ('step' => array('instrument' => 'Lasik 2000', 'pulseEnergy' => 5.4, 'pulseDuration' => 12, 'repetition' => 1000, 'spotSize' => '1mm')),
|
17 |
+
array ('step' => array('instrument' => 'Lasik 2000', 'pulseEnergy' => 5.4, 'pulseDuration' => 12, 'repetition' => 1000, 'spotSize' => '2mm')),
|
18 |
+
);
|
19 |
+
$Actual = spyc_load_file ('indent_1.yaml');
|
20 |
+
$this->assertEquals ($Expected, $Actual['steps']);
|
21 |
+
}
|
22 |
+
|
23 |
+
public function testDeathMasks() {
|
24 |
+
$Expected = array ('sad' => 2, 'magnificent' => 4);
|
25 |
+
$Actual = spyc_load_file ('indent_1.yaml');
|
26 |
+
$this->assertEquals ($Expected, $Actual['death masks are']);
|
27 |
+
}
|
28 |
+
|
29 |
+
public function testDevDb() {
|
30 |
+
$Expected = array ('adapter' => 'mysql', 'host' => 'localhost', 'database' => 'rails_dev');
|
31 |
+
$Actual = spyc_load_file ('indent_1.yaml');
|
32 |
+
$this->assertEquals ($Expected, $Actual['development']);
|
33 |
+
}
|
34 |
+
|
35 |
+
public function testNumericKey() {
|
36 |
+
$this->assertEquals ("Ooo, a numeric key!", $this->yaml[1040]);
|
37 |
+
}
|
38 |
+
|
39 |
+
public function testMappingsString() {
|
40 |
+
$this->assertEquals ("Anyone's name, really.", $this->yaml['String']);
|
41 |
+
}
|
42 |
+
|
43 |
+
public function testMappingsInt() {
|
44 |
+
$this->assertSame (13, $this->yaml['Int']);
|
45 |
+
}
|
46 |
+
|
47 |
+
public function testMappingsBooleanTrue() {
|
48 |
+
$this->assertSame (true, $this->yaml['True']);
|
49 |
+
}
|
50 |
+
|
51 |
+
public function testMappingsBooleanFalse() {
|
52 |
+
$this->assertSame (false, $this->yaml['False']);
|
53 |
+
}
|
54 |
+
|
55 |
+
public function testMappingsZero() {
|
56 |
+
$this->assertSame (0, $this->yaml['Zero']);
|
57 |
+
}
|
58 |
+
|
59 |
+
public function testMappingsNull() {
|
60 |
+
$this->assertSame (null, $this->yaml['Null']);
|
61 |
+
}
|
62 |
+
|
63 |
+
public function testMappingsNotNull() {
|
64 |
+
$this->assertSame ('null', $this->yaml['NotNull']);
|
65 |
+
}
|
66 |
+
|
67 |
+
public function testMappingsFloat() {
|
68 |
+
$this->assertSame (5.34, $this->yaml['Float']);
|
69 |
+
}
|
70 |
+
|
71 |
+
public function testMappingsNegative() {
|
72 |
+
$this->assertSame (-90, $this->yaml['Negative']);
|
73 |
+
}
|
74 |
+
|
75 |
+
public function testMappingsSmallFloat() {
|
76 |
+
$this->assertSame (0.7, $this->yaml['SmallFloat']);
|
77 |
+
}
|
78 |
+
|
79 |
+
public function testNewline() {
|
80 |
+
$this->assertSame ("\n", $this->yaml['NewLine']);
|
81 |
+
}
|
82 |
+
|
83 |
+
|
84 |
+
public function testSeq0() {
|
85 |
+
$this->assertEquals ("PHP Class", $this->yaml[0]);
|
86 |
+
}
|
87 |
+
|
88 |
+
public function testSeq1() {
|
89 |
+
$this->assertEquals ("Basic YAML Loader", $this->yaml[1]);
|
90 |
+
}
|
91 |
+
|
92 |
+
public function testSeq2() {
|
93 |
+
$this->assertEquals ("Very Basic YAML Dumper", $this->yaml[2]);
|
94 |
+
}
|
95 |
+
|
96 |
+
public function testSeq3() {
|
97 |
+
$this->assertEquals (array("YAML is so easy to learn.",
|
98 |
+
"Your config files will never be the same."), $this->yaml[3]);
|
99 |
+
}
|
100 |
+
|
101 |
+
public function testSeqMap() {
|
102 |
+
$this->assertEquals (array("cpu" => "1.5ghz", "ram" => "1 gig",
|
103 |
+
"os" => "os x 10.4.1"), $this->yaml[4]);
|
104 |
+
}
|
105 |
+
|
106 |
+
public function testMappedSequence() {
|
107 |
+
$this->assertEquals (array("yaml.org", "php.net"), $this->yaml['domains']);
|
108 |
+
}
|
109 |
+
|
110 |
+
public function testAnotherSequence() {
|
111 |
+
$this->assertEquals (array("program" => "Adium", "platform" => "OS X",
|
112 |
+
"type" => "Chat Client"), $this->yaml[5]);
|
113 |
+
}
|
114 |
+
|
115 |
+
public function testFoldedBlock() {
|
116 |
+
$this->assertEquals ("There isn't any time for your tricks!\nDo you understand?", $this->yaml['no time']);
|
117 |
+
}
|
118 |
+
|
119 |
+
public function testLiteralAsMapped() {
|
120 |
+
$this->assertEquals ("There is nothing but time\nfor your tricks.", $this->yaml['some time']);
|
121 |
+
}
|
122 |
+
|
123 |
+
public function testCrazy() {
|
124 |
+
$this->assertEquals (array( array("name" => "spartan", "notes" =>
|
125 |
+
array( "Needs to be backed up",
|
126 |
+
"Needs to be normalized" ),
|
127 |
+
"type" => "mysql" )), $this->yaml['databases']);
|
128 |
+
}
|
129 |
+
|
130 |
+
public function testColons() {
|
131 |
+
$this->assertEquals ("like", $this->yaml["if: you'd"]);
|
132 |
+
}
|
133 |
+
|
134 |
+
public function testInline() {
|
135 |
+
$this->assertEquals (array("One", "Two", "Three", "Four"), $this->yaml[6]);
|
136 |
+
}
|
137 |
+
|
138 |
+
public function testNestedInline() {
|
139 |
+
$this->assertEquals (array("One", array("Two", "And", "Three"), "Four", "Five"), $this->yaml[7]);
|
140 |
+
}
|
141 |
+
|
142 |
+
public function testNestedNestedInline() {
|
143 |
+
$this->assertEquals (array( "This", array("Is", "Getting", array("Ridiculous", "Guys")),
|
144 |
+
"Seriously", array("Show", "Mercy")), $this->yaml[8]);
|
145 |
+
}
|
146 |
+
|
147 |
+
public function testInlineMappings() {
|
148 |
+
$this->assertEquals (array("name" => "chris", "age" => "young", "brand" => "lucky strike"), $this->yaml[9]);
|
149 |
+
}
|
150 |
+
|
151 |
+
public function testNestedInlineMappings() {
|
152 |
+
$this->assertEquals (array("name" => "mark", "age" => "older than chris",
|
153 |
+
"brand" => array("marlboro", "lucky strike")), $this->yaml[10]);
|
154 |
+
}
|
155 |
+
|
156 |
+
public function testReferences() {
|
157 |
+
$this->assertEquals (array('Perl', 'Python', 'PHP', 'Ruby'), $this->yaml['dynamic languages']);
|
158 |
+
}
|
159 |
+
|
160 |
+
public function testReferences2() {
|
161 |
+
$this->assertEquals (array('C/C++', 'Java'), $this->yaml['compiled languages']);
|
162 |
+
}
|
163 |
+
|
164 |
+
public function testReferences3() {
|
165 |
+
$this->assertEquals (array(
|
166 |
+
array('Perl', 'Python', 'PHP', 'Ruby'),
|
167 |
+
array('C/C++', 'Java')
|
168 |
+
), $this->yaml['all languages']);
|
169 |
+
}
|
170 |
+
|
171 |
+
public function testEscapedQuotes() {
|
172 |
+
$this->assertEquals ("you know, this shouldn't work. but it does.", $this->yaml[11]);
|
173 |
+
}
|
174 |
+
|
175 |
+
public function testEscapedQuotes_2() {
|
176 |
+
$this->assertEquals ( "that's my value.", $this->yaml[12]);
|
177 |
+
}
|
178 |
+
|
179 |
+
public function testEscapedQuotes_3() {
|
180 |
+
$this->assertEquals ("again, that's my value.", $this->yaml[13]);
|
181 |
+
}
|
182 |
+
|
183 |
+
public function testQuotes() {
|
184 |
+
$this->assertEquals ("here's to \"quotes\", boss.", $this->yaml[14]);
|
185 |
+
}
|
186 |
+
|
187 |
+
public function testQuoteSequence() {
|
188 |
+
$this->assertEquals ( array( 'name' => "Foo, Bar's", 'age' => 20), $this->yaml[15]);
|
189 |
+
}
|
190 |
+
|
191 |
+
public function testShortSequence() {
|
192 |
+
$this->assertEquals (array( 0 => "a", 1 => array (0 => 1, 1 => 2), 2 => "b"), $this->yaml[16]);
|
193 |
+
}
|
194 |
+
|
195 |
+
public function testHash_1() {
|
196 |
+
$this->assertEquals ("Hash", $this->yaml['hash_1']);
|
197 |
+
}
|
198 |
+
|
199 |
+
public function testHash_2() {
|
200 |
+
$this->assertEquals ('Hash #and a comment', $this->yaml['hash_2']);
|
201 |
+
}
|
202 |
+
|
203 |
+
public function testHash_3() {
|
204 |
+
$this->assertEquals ('Hash (#) can appear in key too', $this->yaml['hash#3']);
|
205 |
+
}
|
206 |
+
|
207 |
+
public function testEndloop() {
|
208 |
+
$this->assertEquals ("Does this line in the end indeed make Spyc go to an infinite loop?", $this->yaml['endloop']);
|
209 |
+
}
|
210 |
+
|
211 |
+
public function testReallyLargeNumber() {
|
212 |
+
$this->assertEquals ('115792089237316195423570985008687907853269984665640564039457584007913129639936', $this->yaml['a_really_large_number']);
|
213 |
+
}
|
214 |
+
|
215 |
+
public function testFloatWithZeros() {
|
216 |
+
$this->assertSame ('1.0', $this->yaml['float_test']);
|
217 |
+
}
|
218 |
+
|
219 |
+
public function testFloatWithQuotes() {
|
220 |
+
$this->assertSame ('1.0', $this->yaml['float_test_with_quotes']);
|
221 |
+
}
|
222 |
+
|
223 |
+
public function testFloatInverse() {
|
224 |
+
$this->assertEquals ('001', $this->yaml['float_inverse_test']);
|
225 |
+
}
|
226 |
+
|
227 |
+
public function testIntArray() {
|
228 |
+
$this->assertEquals (array (1, 2, 3), $this->yaml['int array']);
|
229 |
+
}
|
230 |
+
|
231 |
+
public function testArrayOnSeveralLines() {
|
232 |
+
$this->assertEquals (array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), $this->yaml['array on several lines']);
|
233 |
+
}
|
234 |
+
|
235 |
+
public function testmoreLessKey() {
|
236 |
+
$this->assertEquals ('<value>', $this->yaml['morelesskey']);
|
237 |
+
}
|
238 |
+
|
239 |
+
public function testArrayOfZero() {
|
240 |
+
$this->assertSame (array(0), $this->yaml['array_of_zero']);
|
241 |
+
}
|
242 |
+
|
243 |
+
public function testSophisticatedArrayOfZero() {
|
244 |
+
$this->assertSame (array('rx' => array ('tx' => array (0))), $this->yaml['sophisticated_array_of_zero']);
|
245 |
+
}
|
246 |
+
|
247 |
+
public function testSwitches() {
|
248 |
+
$this->assertEquals (array (array ('row' => 0, 'col' => 0, 'func' => array ('tx' => array(0, 1)))), $this->yaml['switches']);
|
249 |
+
}
|
250 |
+
|
251 |
+
public function testEmptySequence() {
|
252 |
+
$this->assertSame (array(), $this->yaml['empty_sequence']);
|
253 |
+
}
|
254 |
+
|
255 |
+
public function testEmptyHash() {
|
256 |
+
$this->assertSame (array(), $this->yaml['empty_hash']);
|
257 |
+
}
|
258 |
+
|
259 |
+
public function testEmptykey() {
|
260 |
+
$this->assertSame (array('' => array ('key' => 'value')), $this->yaml['empty_key']);
|
261 |
+
}
|
262 |
+
|
263 |
+
public function testMultilines() {
|
264 |
+
$this->assertSame (array(array('type' => 'SomeItem', 'values' => array ('blah', 'blah', 'blah', 'blah'), 'ints' => array(2, 54, 12, 2143))), $this->yaml['multiline_items']);
|
265 |
+
}
|
266 |
+
|
267 |
+
public function testManyNewlines() {
|
268 |
+
$this->assertSame ('A quick
|
269 |
+
fox
|
270 |
+
|
271 |
+
|
272 |
+
jumped
|
273 |
+
over
|
274 |
+
|
275 |
+
|
276 |
+
|
277 |
+
|
278 |
+
|
279 |
+
a lazy
|
280 |
+
|
281 |
+
|
282 |
+
|
283 |
+
dog', $this->yaml['many_lines']);
|
284 |
+
}
|
285 |
+
|
286 |
+
public function testWerte() {
|
287 |
+
$this->assertSame (array ('1' => 'nummer 1', '0' => 'Stunde 0'), $this->yaml['werte']);
|
288 |
+
}
|
289 |
+
|
290 |
+
/* public function testNoIndent() {
|
291 |
+
$this->assertSame (array(
|
292 |
+
array ('record1'=>'value1'),
|
293 |
+
array ('record2'=>'value2')
|
294 |
+
)
|
295 |
+
, $this->yaml['noindent_records']);
|
296 |
+
} */
|
297 |
+
|
298 |
+
public function testColonsInKeys() {
|
299 |
+
$this->assertSame (array (1000), $this->yaml['a:1']);
|
300 |
+
}
|
301 |
+
|
302 |
+
public function testColonsInKeys2() {
|
303 |
+
$this->assertSame (array (2000), $this->yaml['a:2']);
|
304 |
+
}
|
305 |
+
|
306 |
+
public function testSpecialCharacters() {
|
307 |
+
$this->assertSame ('[{]]{{]]', $this->yaml['special_characters']);
|
308 |
+
}
|
309 |
+
|
310 |
+
public function testAngleQuotes() {
|
311 |
+
$Quotes = Spyc::YAMLLoad('quotes.yaml');
|
312 |
+
$this->assertEquals (array ('html_tags' => array ('<br>', '<p>'), 'html_content' => array ('<p>hello world</p>', 'hello<br>world'), 'text_content' => array ('hello world')),
|
313 |
+
$Quotes);
|
314 |
+
}
|
315 |
+
|
316 |
+
public function testFailingColons() {
|
317 |
+
$Failing = Spyc::YAMLLoad('failing1.yaml');
|
318 |
+
$this->assertSame (array ('MyObject' => array ('Prop1' => array ('key1:val1'))),
|
319 |
+
$Failing);
|
320 |
+
}
|
321 |
+
|
322 |
+
}
|
includes/admin/uaparser/lib/spyc-0.5/tests/RoundTripTest.php
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once ("../spyc.php");
|
4 |
+
|
5 |
+
function roundTrip($a) { return Spyc::YAMLLoad(Spyc::YAMLDump(array('x' => $a))); }
|
6 |
+
|
7 |
+
|
8 |
+
class RoundTripTest extends PHPUnit_Framework_TestCase {
|
9 |
+
|
10 |
+
protected function setUp() {
|
11 |
+
}
|
12 |
+
|
13 |
+
public function testNull() {
|
14 |
+
$this->assertEquals (array ('x' => null), roundTrip (null));
|
15 |
+
}
|
16 |
+
|
17 |
+
public function testY() {
|
18 |
+
$this->assertEquals (array ('x' => 'y'), roundTrip ('y'));
|
19 |
+
}
|
20 |
+
|
21 |
+
public function testExclam() {
|
22 |
+
$this->assertEquals (array ('x' => '!yeah'), roundTrip ('!yeah'));
|
23 |
+
}
|
24 |
+
|
25 |
+
public function test5() {
|
26 |
+
$this->assertEquals (array ('x' => '5'), roundTrip ('5'));
|
27 |
+
}
|
28 |
+
|
29 |
+
public function testSpaces() {
|
30 |
+
$this->assertEquals (array ('x' => 'x '), roundTrip ('x '));
|
31 |
+
}
|
32 |
+
|
33 |
+
public function testApostrophes() {
|
34 |
+
$this->assertEquals (array ('x' => "'biz'"), roundTrip ("'biz'"));
|
35 |
+
}
|
36 |
+
|
37 |
+
public function testNewLines() {
|
38 |
+
$this->assertEquals (array ('x' => "\n"), roundTrip ("\n"));
|
39 |
+
}
|
40 |
+
|
41 |
+
public function testHashes() {
|
42 |
+
$this->assertEquals (array ('x' => array ("#color" => '#fff')), roundTrip (array ("#color" => '#fff')));
|
43 |
+
}
|
44 |
+
|
45 |
+
public function testWordWrap() {
|
46 |
+
$this->assertEquals (array ('x' => "aaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), roundTrip ("aaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
|
47 |
+
}
|
48 |
+
|
49 |
+
public function testABCD() {
|
50 |
+
$this->assertEquals (array ('a', 'b', 'c', 'd'), Spyc::YAMLLoad(Spyc::YAMLDump(array('a', 'b', 'c', 'd'))));
|
51 |
+
}
|
52 |
+
|
53 |
+
public function testABCD2() {
|
54 |
+
$a = array('a', 'b', 'c', 'd'); // Create a simple list
|
55 |
+
$b = Spyc::YAMLDump($a); // Dump the list as YAML
|
56 |
+
$c = Spyc::YAMLLoad($b); // Load the dumped YAML
|
57 |
+
$d = Spyc::YAMLDump($c); // Re-dump the data
|
58 |
+
$this->assertSame($b, $d);
|
59 |
+
}
|
60 |
+
|
61 |
+
}
|
includes/admin/uaparser/lib/spyc-0.5/tests/failing1.yaml
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
MyObject:
|
2 |
+
Prop1: {key1:val1}
|
includes/admin/uaparser/lib/spyc-0.5/tests/indent_1.yaml
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
root:
|
2 |
+
child_1: 2
|
3 |
+
|
4 |
+
child_2: 0
|
5 |
+
child_3: 1
|
6 |
+
|
7 |
+
root2:
|
8 |
+
child_1: 1
|
9 |
+
# A comment
|
10 |
+
child_2: 2
|
11 |
+
|
12 |
+
displays:
|
13 |
+
- resolutions:
|
14 |
+
1024: 768
|
15 |
+
- resolutions:
|
16 |
+
1920: 1200
|
17 |
+
|
18 |
+
display:
|
19 |
+
- resolutions:
|
20 |
+
1024: 768
|
21 |
+
1920: 1200
|
22 |
+
producer: "Nec"
|
23 |
+
|
24 |
+
nested_hashes_and_seqs:
|
25 |
+
- { row: 0, col: 0, headsets_affected: [{ports: [0], side: left}], switch_function: {ics_ptt: true} }
|
26 |
+
|
27 |
+
easier_nest: { h: [{a: b, a1: b1}, {c: d}] }
|
28 |
+
|
29 |
+
one_space: |
|
30 |
+
By four
|
31 |
+
spaces
|
32 |
+
|
33 |
+
steps:
|
34 |
+
- step: &id001
|
35 |
+
instrument: Lasik 2000
|
36 |
+
pulseEnergy: 5.4
|
37 |
+
pulseDuration: 12
|
38 |
+
repetition: 1000
|
39 |
+
spotSize: 1mm
|
40 |
+
- step:
|
41 |
+
<<: *id001
|
42 |
+
spotSize: 2mm
|
43 |
+
|
44 |
+
death masks are:
|
45 |
+
sad: 2
|
46 |
+
<<: {magnificent: 4}
|
47 |
+
|
48 |
+
login: &login
|
49 |
+
adapter: mysql
|
50 |
+
host: localhost
|
51 |
+
|
52 |
+
development:
|
53 |
+
database: rails_dev
|
54 |
+
<<: *login
|
55 |
+
|
56 |
+
"key": "value:"
|
57 |
+
colon_only: ":"
|
58 |
+
|
59 |
+
list_and_comment: [one, two, three] # comment
|
includes/admin/uaparser/lib/spyc-0.5/tests/quotes.yaml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
html_tags:
|
2 |
+
- <br>
|
3 |
+
- <p>
|
4 |
+
html_content:
|
5 |
+
- <p>hello world</p>
|
6 |
+
- hello<br>world
|
7 |
+
text_content:
|
8 |
+
- hello world
|
includes/admin/uaparser/log/.gitignore
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
*.txt
|
2 |
+
*.log
|
includes/admin/uaparser/log/README.md
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
If you turn on debug mode this is where your results will be logged.
|
includes/admin/uaparser/resources/regexes.json
ADDED
@@ -0,0 +1,1193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"user_agent_parsers": [
|
3 |
+
{
|
4 |
+
"regex": "(SeaMonkey|Camino)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)"
|
5 |
+
},
|
6 |
+
{
|
7 |
+
"regex": "(Pale[Mm]oon)/(\\d+)\\.(\\d+)\\.?(\\d+)?",
|
8 |
+
"family_replacement": "Pale Moon (Firefox Variant)"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"regex": "(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)",
|
12 |
+
"family_replacement": "Firefox Mobile"
|
13 |
+
},
|
14 |
+
{
|
15 |
+
"regex": "(Fennec)/(\\d+)\\.(\\d+)(pre)",
|
16 |
+
"family_replacement": "Firefox Mobile"
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"regex": "(Fennec)/(\\d+)\\.(\\d+)",
|
20 |
+
"family_replacement": "Firefox Mobile"
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"regex": "Mobile.*(Firefox)/(\\d+)\\.(\\d+)",
|
24 |
+
"family_replacement": "Firefox Mobile"
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"regex": "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?)",
|
28 |
+
"family_replacement": "Firefox ($1)"
|
29 |
+
},
|
30 |
+
{
|
31 |
+
"regex": "(Firefox)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)",
|
32 |
+
"family_replacement": "Firefox Alpha"
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"regex": "(Firefox)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)",
|
36 |
+
"family_replacement": "Firefox Beta"
|
37 |
+
},
|
38 |
+
{
|
39 |
+
"regex": "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(a\\d+[a-z]*)",
|
40 |
+
"family_replacement": "Firefox Alpha"
|
41 |
+
},
|
42 |
+
{
|
43 |
+
"regex": "(Firefox)-(?:\\d+\\.\\d+)?/(\\d+)\\.(\\d+)(b\\d+[a-z]*)",
|
44 |
+
"family_replacement": "Firefox Beta"
|
45 |
+
},
|
46 |
+
{
|
47 |
+
"regex": "(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?",
|
48 |
+
"family_replacement": "Firefox ($1)"
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"regex": "(Firefox).*Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)",
|
52 |
+
"family_replacement": "MicroB"
|
53 |
+
},
|
54 |
+
{
|
55 |
+
"regex": "(MozillaDeveloperPreview)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?"
|
56 |
+
},
|
57 |
+
{
|
58 |
+
"regex": "(Flock)/(\\d+)\\.(\\d+)(b\\d+?)"
|
59 |
+
},
|
60 |
+
{
|
61 |
+
"regex": "(RockMelt)/(\\d+)\\.(\\d+)\\.(\\d+)"
|
62 |
+
},
|
63 |
+
{
|
64 |
+
"regex": "(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
65 |
+
"family_replacement": "Netscape"
|
66 |
+
},
|
67 |
+
{
|
68 |
+
"regex": "(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)",
|
69 |
+
"family_replacement": "Netscape"
|
70 |
+
},
|
71 |
+
{
|
72 |
+
"regex": "(Netscape6)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
73 |
+
"family_replacement": "Netscape"
|
74 |
+
},
|
75 |
+
{
|
76 |
+
"regex": "(MyIBrow)/(\\d+)\\.(\\d+)",
|
77 |
+
"family_replacement": "My Internet Browser"
|
78 |
+
},
|
79 |
+
{
|
80 |
+
"regex": "(Opera Tablet).*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?"
|
81 |
+
},
|
82 |
+
{
|
83 |
+
"regex": "(Opera)/.+Opera Mobi.+Version/(\\d+)\\.(\\d+)",
|
84 |
+
"family_replacement": "Opera Mobile"
|
85 |
+
},
|
86 |
+
{
|
87 |
+
"regex": "Opera Mobi",
|
88 |
+
"family_replacement": "Opera Mobile"
|
89 |
+
},
|
90 |
+
{
|
91 |
+
"regex": "(Opera Mini)/(\\d+)\\.(\\d+)"
|
92 |
+
},
|
93 |
+
{
|
94 |
+
"regex": "(Opera Mini)/att/(\\d+)\\.(\\d+)"
|
95 |
+
},
|
96 |
+
{
|
97 |
+
"regex": "(Opera)/9.80.*Version/(\\d+)\\.(\\d+)(?:\\.(\\d+))?"
|
98 |
+
},
|
99 |
+
{
|
100 |
+
"regex": "(?:Mobile Safari).*(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
101 |
+
"family_replacement": "Opera Mobile"
|
102 |
+
},
|
103 |
+
{
|
104 |
+
"regex": "(?:Chrome).*(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
105 |
+
"family_replacement": "Opera"
|
106 |
+
},
|
107 |
+
{
|
108 |
+
"regex": "(hpw|web)OS/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
|
109 |
+
"family_replacement": "webOS Browser"
|
110 |
+
},
|
111 |
+
{
|
112 |
+
"regex": "(luakit)",
|
113 |
+
"family_replacement": "LuaKit"
|
114 |
+
},
|
115 |
+
{
|
116 |
+
"regex": "(Snowshoe)/(\\d+)\\.(\\d+).(\\d+)"
|
117 |
+
},
|
118 |
+
{
|
119 |
+
"regex": "(Lightning)/(\\d+)\\.(\\d+)([ab]?\\d+[a-z]*)"
|
120 |
+
},
|
121 |
+
{
|
122 |
+
"regex": "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?) \\(Swiftfox\\)",
|
123 |
+
"family_replacement": "Swiftfox"
|
124 |
+
},
|
125 |
+
{
|
126 |
+
"regex": "(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)? \\(Swiftfox\\)",
|
127 |
+
"family_replacement": "Swiftfox"
|
128 |
+
},
|
129 |
+
{
|
130 |
+
"regex": "(rekonq)/(\\d+)\\.(\\d+)\\.?(\\d+)? Safari",
|
131 |
+
"family_replacement": "Rekonq"
|
132 |
+
},
|
133 |
+
{
|
134 |
+
"regex": "rekonq",
|
135 |
+
"family_replacement": "Rekonq"
|
136 |
+
},
|
137 |
+
{
|
138 |
+
"regex": "(conkeror|Conkeror)/(\\d+)\\.(\\d+)\\.?(\\d+)?",
|
139 |
+
"family_replacement": "Conkeror"
|
140 |
+
},
|
141 |
+
{
|
142 |
+
"regex": "(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
143 |
+
"family_replacement": "Konqueror"
|
144 |
+
},
|
145 |
+
{
|
146 |
+
"regex": "(WeTab)-Browser"
|
147 |
+
},
|
148 |
+
{
|
149 |
+
"regex": "(Comodo_Dragon)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
150 |
+
"family_replacement": "Comodo Dragon"
|
151 |
+
},
|
152 |
+
{
|
153 |
+
"regex": "(YottaaMonitor|BrowserMob|HttpMonitor|YandexBot|Slurp|BingPreview|PagePeeker|ThumbShotsBot|WebThumb|URL2PNG|ZooShot|GomezA|Catchpoint bot|Willow Internet Crawler|Google SketchUp|Read%20Later)"
|
154 |
+
},
|
155 |
+
{
|
156 |
+
"regex": "(Symphony) (\\d+).(\\d+)"
|
157 |
+
},
|
158 |
+
{
|
159 |
+
"regex": "(Minimo)"
|
160 |
+
},
|
161 |
+
{
|
162 |
+
"regex": "(CrMo)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
|
163 |
+
"family_replacement": "Chrome Mobile"
|
164 |
+
},
|
165 |
+
{
|
166 |
+
"regex": "(CriOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
|
167 |
+
"family_replacement": "Chrome Mobile iOS"
|
168 |
+
},
|
169 |
+
{
|
170 |
+
"regex": "(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile",
|
171 |
+
"family_replacement": "Chrome Mobile"
|
172 |
+
},
|
173 |
+
{
|
174 |
+
"regex": "(chromeframe)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
175 |
+
"family_replacement": "Chrome Frame"
|
176 |
+
},
|
177 |
+
{
|
178 |
+
"regex": "(UCBrowser)[ /](\\d+)\\.(\\d+)\\.(\\d+)",
|
179 |
+
"family_replacement": "UC Browser"
|
180 |
+
},
|
181 |
+
{
|
182 |
+
"regex": "(UC Browser)[ /](\\d+)\\.(\\d+)\\.(\\d+)"
|
183 |
+
},
|
184 |
+
{
|
185 |
+
"regex": "(UC Browser|UCBrowser|UCWEB)(\\d+)\\.(\\d+)\\.(\\d+)",
|
186 |
+
"family_replacement": "UC Browser"
|
187 |
+
},
|
188 |
+
{
|
189 |
+
"regex": "(SLP Browser)/(\\d+)\\.(\\d+)",
|
190 |
+
"family_replacement": "Tizen Browser"
|
191 |
+
},
|
192 |
+
{
|
193 |
+
"regex": "(SE 2\\.X) MetaSr (\\d+)\\.(\\d+)",
|
194 |
+
"family_replacement": "Sogou Explorer"
|
195 |
+
},
|
196 |
+
{
|
197 |
+
"regex": "(baidubrowser)[/\\s](\\d+)",
|
198 |
+
"family_replacement": "Baidu Browser"
|
199 |
+
},
|
200 |
+
{
|
201 |
+
"regex": "(FlyFlow)/(\\d+)\\.(\\d+)",
|
202 |
+
"family_replacement": "Baidu Explorer"
|
203 |
+
},
|
204 |
+
{
|
205 |
+
"regex": "(Pingdom.com_bot_version_)(\\d+)\\.(\\d+)",
|
206 |
+
"family_replacement": "PingdomBot"
|
207 |
+
},
|
208 |
+
{
|
209 |
+
"regex": "(facebookexternalhit)/(\\d+)\\.(\\d+)",
|
210 |
+
"family_replacement": "FacebookBot"
|
211 |
+
},
|
212 |
+
{
|
213 |
+
"regex": "(Twitterbot)/(\\d+)\\.(\\d+)",
|
214 |
+
"family_replacement": "TwitterBot"
|
215 |
+
},
|
216 |
+
{
|
217 |
+
"regex": "(Rackspace Monitoring)/(\\d+)\\.(\\d+)",
|
218 |
+
"family_replacement": "RackspaceBot"
|
219 |
+
},
|
220 |
+
{
|
221 |
+
"regex": "(PyAMF)/(\\d+)\\.(\\d+)\\.(\\d+)"
|
222 |
+
},
|
223 |
+
{
|
224 |
+
"regex": "(YaBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
225 |
+
"family_replacement": "Yandex Browser"
|
226 |
+
},
|
227 |
+
{
|
228 |
+
"regex": "(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+).* MRCHROME",
|
229 |
+
"family_replacement": "Mail.ru Chromium Browser"
|
230 |
+
},
|
231 |
+
{
|
232 |
+
"regex": "(AOL) (\\d+)\\.(\\d+); AOLBuild (\\d+)"
|
233 |
+
},
|
234 |
+
{
|
235 |
+
"regex": "(AdobeAIR|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Epiphany|Shiira|Sunrise|Flock|Netscape|Lunascape|WebPilot|Vodafone|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iris|UP\\.Browser|Bunjalloo|Google Earth|Raven for Mac|Openwave)/(\\d+)\\.(\\d+)\\.(\\d+)"
|
236 |
+
},
|
237 |
+
{
|
238 |
+
"regex": "(Chromium|Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)"
|
239 |
+
},
|
240 |
+
{
|
241 |
+
"regex": "(Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|Vodafone|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser)/(\\d+)\\.(\\d+)"
|
242 |
+
},
|
243 |
+
{
|
244 |
+
"regex": "(Chromium|Chrome)/(\\d+)\\.(\\d+)"
|
245 |
+
},
|
246 |
+
{
|
247 |
+
"regex": "(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)"
|
248 |
+
},
|
249 |
+
{
|
250 |
+
"regex": "(iCab|Lunascape|Opera|Android|Jasmine|Polaris) (\\d+)\\.(\\d+)\\.?(\\d+)?"
|
251 |
+
},
|
252 |
+
{
|
253 |
+
"regex": "(Kindle)/(\\d+)\\.(\\d+)"
|
254 |
+
},
|
255 |
+
{
|
256 |
+
"regex": "(Android) Donut",
|
257 |
+
"v2_replacement": "2",
|
258 |
+
"v1_replacement": "1"
|
259 |
+
},
|
260 |
+
{
|
261 |
+
"regex": "(Android) Eclair",
|
262 |
+
"v2_replacement": "1",
|
263 |
+
"v1_replacement": "2"
|
264 |
+
},
|
265 |
+
{
|
266 |
+
"regex": "(Android) Froyo",
|
267 |
+
"v2_replacement": "2",
|
268 |
+
"v1_replacement": "2"
|
269 |
+
},
|
270 |
+
{
|
271 |
+
"regex": "(Android) Gingerbread",
|
272 |
+
"v2_replacement": "3",
|
273 |
+
"v1_replacement": "2"
|
274 |
+
},
|
275 |
+
{
|
276 |
+
"regex": "(Android) Honeycomb",
|
277 |
+
"v1_replacement": "3"
|
278 |
+
},
|
279 |
+
{
|
280 |
+
"regex": "(IEMobile)[ /](\\d+)\\.(\\d+)",
|
281 |
+
"family_replacement": "IE Mobile"
|
282 |
+
},
|
283 |
+
{
|
284 |
+
"regex": "(MSIE) (\\d+)\\.(\\d+).*XBLWP7",
|
285 |
+
"family_replacement": "IE Large Screen"
|
286 |
+
},
|
287 |
+
{
|
288 |
+
"regex": "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)"
|
289 |
+
},
|
290 |
+
{
|
291 |
+
"regex": "(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*)?"
|
292 |
+
},
|
293 |
+
{
|
294 |
+
"regex": "(Obigo)InternetBrowser"
|
295 |
+
},
|
296 |
+
{
|
297 |
+
"regex": "(Obigo)\\-Browser"
|
298 |
+
},
|
299 |
+
{
|
300 |
+
"regex": "(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+))?",
|
301 |
+
"family_replacement": "Obigo"
|
302 |
+
},
|
303 |
+
{
|
304 |
+
"regex": "(MAXTHON|Maxthon) (\\d+)\\.(\\d+)",
|
305 |
+
"family_replacement": "Maxthon"
|
306 |
+
},
|
307 |
+
{
|
308 |
+
"regex": "(Maxthon|MyIE2|Uzbl|Shiira)",
|
309 |
+
"v1_replacement": "0"
|
310 |
+
},
|
311 |
+
{
|
312 |
+
"regex": "PLAYSTATION 3.+WebKit",
|
313 |
+
"family_replacement": "NetFront NX"
|
314 |
+
},
|
315 |
+
{
|
316 |
+
"regex": "PLAYSTATION 3",
|
317 |
+
"family_replacement": "NetFront"
|
318 |
+
},
|
319 |
+
{
|
320 |
+
"regex": "(PlayStation Portable)",
|
321 |
+
"family_replacement": "NetFront"
|
322 |
+
},
|
323 |
+
{
|
324 |
+
"regex": "(PlayStation Vita)",
|
325 |
+
"family_replacement": "NetFront NX"
|
326 |
+
},
|
327 |
+
{
|
328 |
+
"regex": "AppleWebKit.+ (NX)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
329 |
+
"family_replacement": "NetFront NX"
|
330 |
+
},
|
331 |
+
{
|
332 |
+
"regex": "(Nintendo 3DS)",
|
333 |
+
"family_replacement": "NetFront NX"
|
334 |
+
},
|
335 |
+
{
|
336 |
+
"regex": "(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)"
|
337 |
+
},
|
338 |
+
{
|
339 |
+
"regex": "(NCSA_Mosaic)/(\\d+)\\.(\\d+)",
|
340 |
+
"family_replacement": "NCSA Mosaic"
|
341 |
+
},
|
342 |
+
{
|
343 |
+
"regex": "(POLARIS)/(\\d+)\\.(\\d+)",
|
344 |
+
"family_replacement": "Polaris"
|
345 |
+
},
|
346 |
+
{
|
347 |
+
"regex": "(Embider)/(\\d+)\\.(\\d+)",
|
348 |
+
"family_replacement": "Polaris"
|
349 |
+
},
|
350 |
+
{
|
351 |
+
"regex": "(BonEcho)/(\\d+)\\.(\\d+)\\.(\\d+)",
|
352 |
+
"family_replacement": "Bon Echo"
|
353 |
+
},
|
354 |
+
{
|
355 |
+
"regex": "M?QQBrowser",
|
356 |
+
"family_replacement": "QQ Browser"
|
357 |
+
},
|
358 |
+
{
|
359 |
+
"regex": "(iPod).+Version/(\\d+)\\.(\\d+)\\.(\\d+)",
|
360 |
+
"family_replacement": "Mobile Safari"
|
361 |
+
},
|
362 |
+
{
|
363 |
+
"regex": "(iPod).*Version/(\\d+)\\.(\\d+)",
|
364 |
+
"family_replacement": "Mobile Safari"
|
365 |
+
},
|
366 |
+
{
|
367 |
+
"regex": "(iPhone).*Version/(\\d+)\\.(\\d+)\\.(\\d+)",
|
368 |
+
"family_replacement": "Mobile Safari"
|
369 |
+
},
|
370 |
+
{
|
371 |
+
"regex": "(iPhone).*Version/(\\d+)\\.(\\d+)",
|
372 |
+
"family_replacement": "Mobile Safari"
|
373 |
+
},
|
374 |
+
{
|
375 |
+
"regex": "(iPad).*Version/(\\d+)\\.(\\d+)\\.(\\d+)",
|
376 |
+
"family_replacement": "Mobile Safari"
|
377 |
+
},
|
378 |
+
{
|
379 |
+
"regex": "(iPad).*Version/(\\d+)\\.(\\d+)",
|
380 |
+
"family_replacement": "Mobile Safari"
|
381 |
+
},
|
382 |
+
{
|
383 |
+
"regex": "(iPod|iPhone|iPad);.*CPU.*OS (\\d+)(?:_\\d+)?_(\\d+).*Mobile",
|
384 |
+
"family_replacement": "Mobile Safari"
|
385 |
+
},
|
386 |
+
{
|
387 |
+
"regex": "(iPod|iPhone|iPad)",
|
388 |
+
"family_replacement": "Mobile Safari"
|
389 |
+
},
|
390 |
+
{
|
391 |
+
"regex": "(AvantGo) (\\d+).(\\d+)"
|
392 |
+
},
|
393 |
+
{
|
394 |
+
"regex": "(OneBrowser)/(\\d+).(\\d+)",
|
395 |
+
"family_replacement": "ONE Browser"
|
396 |
+
},
|
397 |
+
{
|
398 |
+
"regex": "(Avant)",
|
399 |
+
"v1_replacement": "1"
|
400 |
+
},
|
401 |
+
{
|
402 |
+
"regex": "(QtCarBrowser)",
|
403 |
+
"v1_replacement": "1"
|
404 |
+
},
|
405 |
+
{
|
406 |
+
"regex": "(iBrowser/Mini)(\\d+).(\\d+)",
|
407 |
+
"family_replacement": "iBrowser Mini"
|
408 |
+
},
|
409 |
+
{
|
410 |
+
"regex": "^(Nokia)",
|
411 |
+
"family_replacement": "Nokia Services (WAP) Browser"
|
412 |
+
},
|
413 |
+
{
|
414 |
+
"regex": "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)\\.(\\d+)",
|
415 |
+
"family_replacement": "Nokia Browser"
|
416 |
+
},
|
417 |
+
{
|
418 |
+
"regex": "(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)",
|
419 |
+
"family_replacement": "Nokia Browser"
|
420 |
+
},
|
421 |
+
{
|
422 |
+
"regex": "(NokiaBrowser)/(\\d+)\\.(\\d+)",
|
423 |
+
"family_replacement": "Nokia Browser"
|
424 |
+
},
|
425 |
+
{
|
426 |
+
"regex": "(BrowserNG)/(\\d+)\\.(\\d+).(\\d+)",
|
427 |
+
"family_replacement": "Nokia Browser"
|
428 |
+
},
|
429 |
+
{
|
430 |
+
"regex": "(Series60)/5\\.0",
|
431 |
+
"v2_replacement": "0",
|
432 |
+
"v1_replacement": "7",
|
433 |
+
"family_replacement": "Nokia Browser"
|
434 |
+
},
|
435 |
+
{
|
436 |
+
"regex": "(Series60)/(\\d+)\\.(\\d+)",
|
437 |
+
"family_replacement": "Nokia OSS Browser"
|
438 |
+
},
|
439 |
+
{
|
440 |
+
"regex": "(S40OviBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
|
441 |
+
"family_replacement": "Ovi Browser"
|
442 |
+
},
|
443 |
+
{
|
444 |
+
"regex": "(Nokia)[EN]?(\\d+)"
|
445 |
+
},
|
446 |
+
{
|
447 |
+
"regex": "(BB10);",
|
448 |
+
"family_replacement": "BlackBerry WebKit"
|
449 |
+
},
|
450 |
+
{
|
451 |
+
"regex": "(PlayBook).+RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)",
|
452 |
+
"family_replacement": "BlackBerry WebKit"
|
453 |
+
},
|
454 |
+
{
|
455 |
+
"regex": "(Black[bB]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)",
|
456 |
+
"family_replacement": "BlackBerry WebKit"
|
457 |
+
},
|
458 |
+
{
|
459 |
+
"regex": "(Black[bB]erry)\\s?(\\d+)",
|
460 |
+
"family_replacement": "BlackBerry"
|
461 |
+
},
|
462 |
+
{
|
463 |
+
"regex": "(OmniWeb)/v(\\d+)\\.(\\d+)"
|
464 |
+
},
|
465 |
+
{
|
466 |
+
"regex": "(Blazer)/(\\d+)\\.(\\d+)",
|
467 |
+
"family_replacement": "Palm Blazer"
|
468 |
+
},
|
469 |
+
{
|
470 |
+
"regex": "(Pre)/(\\d+)\\.(\\d+)",
|
471 |
+
"family_replacement": "Palm Pre"
|
472 |
+
},
|
473 |
+
{
|
474 |
+
"regex": "(Links) \\((\\d+)\\.(\\d+)"
|
475 |
+
},
|
476 |
+
{
|
477 |
+
"regex": "(QtWeb) Internet Browser/(\\d+)\\.(\\d+)"
|
478 |
+
},
|
479 |
+
{
|
480 |
+
"regex": "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?",
|
481 |
+
"family_replacement": "Amazon Silk"
|
482 |
+
},
|
483 |
+
{
|
484 |
+
"regex": "(PhantomJS)/(\\d+)\\.(\\d+)\\.(\\d+)"
|
485 |
+
},
|
486 |
+
{
|
487 |
+
"regex": "(AppleWebKit)/(\\d+)\\.?(\\d+)?\\+ .* Safari",
|
488 |
+
"family_replacement": "WebKit Nightly"
|
489 |
+
},
|
490 |
+
{
|
491 |
+
"regex": "(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*Safari/",
|
492 |
+
"family_replacement": "Safari"
|
493 |
+
},
|
494 |
+
{
|
495 |
+
"regex": "(Safari)/\\d+"
|
496 |
+
},
|
497 |
+
{
|
498 |
+
"regex": "(OLPC)/Update(\\d+)\\.(\\d+)"
|
499 |
+
},
|
500 |
+
{
|
501 |
+
"regex": "(OLPC)/Update()\\.(\\d+)",
|
502 |
+
"v1_replacement": "0"
|
503 |
+
},
|
504 |
+
{
|
505 |
+
"regex": "(SEMC\\-Browser)/(\\d+)\\.(\\d+)"
|
506 |
+
},
|
507 |
+
{
|
508 |
+
"regex": "(Teleca)",
|
509 |
+
"family_replacement": "Teleca Browser"
|
510 |
+
},
|
511 |
+
{
|
512 |
+
"regex": "(Phantom)/V(\\d+)\\.(\\d+)",
|
513 |
+
"family_replacement": "Phantom Browser"
|
514 |
+
},
|
515 |
+
{
|
516 |
+
"regex": "([MS]?IE) (\\d+)\\.(\\d+)",
|
517 |
+
"family_replacement": "IE"
|
518 |
+
},
|
519 |
+
{
|
520 |
+
"regex": "(python-requests)/(\\d+)\\.(\\d+)",
|
521 |
+
"family_replacement": "Python Requests"
|
522 |
+
}
|
523 |
+
],
|
524 |
+
"os_parsers": [
|
525 |
+
{
|
526 |
+
"regex": "(Android) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"
|
527 |
+
},
|
528 |
+
{
|
529 |
+
"regex": "(Android)\\-(\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]+))?"
|
530 |
+
},
|
531 |
+
{
|
532 |
+
"regex": "(Android) Donut",
|
533 |
+
"os_v2_replacement": "2",
|
534 |
+
"os_v1_replacement": "1"
|
535 |
+
},
|
536 |
+
{
|
537 |
+
"regex": "(Android) Eclair",
|
538 |
+
"os_v2_replacement": "1",
|
539 |
+
"os_v1_replacement": "2"
|
540 |
+
},
|
541 |
+
{
|
542 |
+
"regex": "(Android) Froyo",
|
543 |
+
"os_v2_replacement": "2",
|
544 |
+
"os_v1_replacement": "2"
|
545 |
+
},
|
546 |
+
{
|
547 |
+
"regex": "(Android) Gingerbread",
|
548 |
+
"os_v2_replacement": "3",
|
549 |
+
"os_v1_replacement": "2"
|
550 |
+
},
|
551 |
+
{
|
552 |
+
"regex": "(Android) Honeycomb",
|
553 |
+
"os_v1_replacement": "3"
|
554 |
+
},
|
555 |
+
{
|
556 |
+
"regex": "(Silk-Accelerated=[a-z]{4,5})",
|
557 |
+
"os_replacement": "Android"
|
558 |
+
},
|
559 |
+
{
|
560 |
+
"regex": "(Windows (?:NT 5\\.2|NT 5\\.1))",
|
561 |
+
"os_replacement": "Windows XP"
|
562 |
+
},
|
563 |
+
{
|
564 |
+
"regex": "(XBLWP7)",
|
565 |
+
"os_replacement": "Windows Phone"
|
566 |
+
},
|
567 |
+
{
|
568 |
+
"regex": "(Windows NT 6\\.1)",
|
569 |
+
"os_replacement": "Windows 7"
|
570 |
+
},
|
571 |
+
{
|
572 |
+
"regex": "(Windows NT 6\\.0)",
|
573 |
+
"os_replacement": "Windows Vista"
|
574 |
+
},
|
575 |
+
{
|
576 |
+
"regex": "(Win 9x 4\\.90)",
|
577 |
+
"os_replacement": "Windows Me"
|
578 |
+
},
|
579 |
+
{
|
580 |
+
"regex": "(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\\.0|Windows Vista|Windows 2000|Windows 3.1)"
|
581 |
+
},
|
582 |
+
{
|
583 |
+
"regex": "(Windows NT 6\\.2; ARM;)",
|
584 |
+
"os_replacement": "Windows RT"
|
585 |
+
},
|
586 |
+
{
|
587 |
+
"regex": "(Windows NT 6\\.2)",
|
588 |
+
"os_replacement": "Windows 8"
|
589 |
+
},
|
590 |
+
{
|
591 |
+
"regex": "(Windows NT 5\\.0)",
|
592 |
+
"os_replacement": "Windows 2000"
|
593 |
+
},
|
594 |
+
{
|
595 |
+
"regex": "(Windows Phone) (\\d+)\\.(\\d+)"
|
596 |
+
},
|
597 |
+
{
|
598 |
+
"regex": "(Windows Phone) OS (\\d+)\\.(\\d+)"
|
599 |
+
},
|
600 |
+
{
|
601 |
+
"regex": "(Windows ?Mobile)",
|
602 |
+
"os_replacement": "Windows Mobile"
|
603 |
+
},
|
604 |
+
{
|
605 |
+
"regex": "(WinNT4.0)",
|
606 |
+
"os_replacement": "Windows NT 4.0"
|
607 |
+
},
|
608 |
+
{
|
609 |
+
"regex": "(Win98)",
|
610 |
+
"os_replacement": "Windows 98"
|
611 |
+
},
|
612 |
+
{
|
613 |
+
"regex": "(Tizen)/(\\d+)\\.(\\d+)"
|
614 |
+
},
|
615 |
+
{
|
616 |
+
"regex": "(Mac OS X) (\\d+)[_.](\\d+)(?:[_.](\\d+))?"
|
617 |
+
},
|
618 |
+
{
|
619 |
+
"regex": "Mac_PowerPC",
|
620 |
+
"os_replacement": "Mac OS"
|
621 |
+
},
|
622 |
+
{
|
623 |
+
"regex": "(?:PPC|Intel) (Mac OS X)"
|
624 |
+
},
|
625 |
+
{
|
626 |
+
"regex": "(CPU OS|iPhone OS) (\\d+)_(\\d+)(?:_(\\d+))?",
|
627 |
+
"os_replacement": "iOS"
|
628 |
+
},
|
629 |
+
{
|
630 |
+
"regex": "(iPhone|iPad|iPod); Opera",
|
631 |
+
"os_replacement": "iOS"
|
632 |
+
},
|
633 |
+
{
|
634 |
+
"regex": "(iPhone|iPad|iPod).*Mac OS X.*Version/(\\d+)\\.(\\d+)",
|
635 |
+
"os_replacement": "iOS"
|
636 |
+
},
|
637 |
+
{
|
638 |
+
"regex": "(AppleTV)/(\\d+)\\.(\\d+)",
|
639 |
+
"os_replacement": "ATV OS X"
|
640 |
+
},
|
641 |
+
{
|
642 |
+
"regex": "(CrOS) [a-z0-9_]+ (\\d+)\\.(\\d+)(?:\\.(\\d+))?",
|
643 |
+
"os_replacement": "Chrome OS"
|
644 |
+
},
|
645 |
+
{
|
646 |
+
"regex": "([Dd]ebian)",
|
647 |
+
"os_replacement": "Debian"
|
648 |
+
},
|
649 |
+
{
|
650 |
+
"regex": "(Linux Mint)(?:/(\\d+))?"
|
651 |
+
},
|
652 |
+
{
|
653 |
+
"regex": "(Mandriva)(?: Linux)?/(?:[\\d.-]+m[a-z]{2}(\\d+).(\\d))?"
|
654 |
+
},
|
655 |
+
{
|
656 |
+
"regex": "(Symbian[Oo][Ss])/(\\d+)\\.(\\d+)",
|
657 |
+
"os_replacement": "Symbian OS"
|
658 |
+
},
|
659 |
+
{
|
660 |
+
"regex": "(Symbian/3).+NokiaBrowser/7\\.3",
|
661 |
+
"os_replacement": "Symbian^3 Anna"
|
662 |
+
},
|
663 |
+
{
|
664 |
+
"regex": "(Symbian/3).+NokiaBrowser/7\\.4",
|
665 |
+
"os_replacement": "Symbian^3 Belle"
|
666 |
+
},
|
667 |
+
{
|
668 |
+
"regex": "(Symbian/3)",
|
669 |
+
"os_replacement": "Symbian^3"
|
670 |
+
},
|
671 |
+
{
|
672 |
+
"regex": "(Series 60|SymbOS|S60)",
|
673 |
+
"os_replacement": "Symbian OS"
|
674 |
+
},
|
675 |
+
{
|
676 |
+
"regex": "(MeeGo)"
|
677 |
+
},
|
678 |
+
{
|
679 |
+
"regex": "Symbian [Oo][Ss]",
|
680 |
+
"os_replacement": "Symbian OS"
|
681 |
+
},
|
682 |
+
{
|
683 |
+
"regex": "Series40;",
|
684 |
+
"os_replacement": "Nokia Series 40"
|
685 |
+
},
|
686 |
+
{
|
687 |
+
"regex": "(BB10);.+Version/(\\d+)\\.(\\d+)\\.(\\d+)",
|
688 |
+
"os_replacement": "BlackBerry OS"
|
689 |
+
},
|
690 |
+
{
|
691 |
+
"regex": "(Black[Bb]erry)[0-9a-z]+/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
|
692 |
+
"os_replacement": "BlackBerry OS"
|
693 |
+
},
|
694 |
+
{
|
695 |
+
"regex": "(Black[Bb]erry).+Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
|
696 |
+
"os_replacement": "BlackBerry OS"
|
697 |
+
},
|
698 |
+
{
|
699 |
+
"regex": "(RIM Tablet OS) (\\d+)\\.(\\d+)\\.(\\d+)",
|
700 |
+
"os_replacement": "BlackBerry Tablet OS"
|
701 |
+
},
|
702 |
+
{
|
703 |
+
"regex": "(Play[Bb]ook)",
|
704 |
+
"os_replacement": "BlackBerry Tablet OS"
|
705 |
+
},
|
706 |
+
{
|
707 |
+
"regex": "(Black[Bb]erry)",
|
708 |
+
"os_replacement": "BlackBerry OS"
|
709 |
+
},
|
710 |
+
{
|
711 |
+
"regex": "\\(Mobile;.+Firefox/\\d+\\.\\d+",
|
712 |
+
"os_replacement": "Firefox OS"
|
713 |
+
},
|
714 |
+
{
|
715 |
+
"regex": "(BREW)[ /](\\d+)\\.(\\d+)\\.(\\d+)"
|
716 |
+
},
|
717 |
+
{
|
718 |
+
"regex": "(BREW);"
|
719 |
+
},
|
720 |
+
{
|
721 |
+
"regex": "(Brew MP|BMP)[ /](\\d+)\\.(\\d+)\\.(\\d+)",
|
722 |
+
"os_replacement": "Brew MP"
|
723 |
+
},
|
724 |
+
{
|
725 |
+
"regex": "BMP;",
|
726 |
+
"os_replacement": "Brew MP"
|
727 |
+
},
|
728 |
+
{
|
729 |
+
"regex": "(GoogleTV) (\\d+)\\.(\\d+)\\.(\\d+)"
|
730 |
+
},
|
731 |
+
{
|
732 |
+
"regex": "(GoogleTV)/\\d+"
|
733 |
+
},
|
734 |
+
{
|
735 |
+
"regex": "(WebTV)/(\\d+).(\\d+)"
|
736 |
+
},
|
737 |
+
{
|
738 |
+
"regex": "(hpw|web)OS/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
|
739 |
+
"os_replacement": "webOS"
|
740 |
+
},
|
741 |
+
{
|
742 |
+
"regex": "(VRE);"
|
743 |
+
},
|
744 |
+
{
|
745 |
+
"regex": "(Fedora|Red Hat|PCLinuxOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"
|
746 |
+
},
|
747 |
+
{
|
748 |
+
"regex": "(Red Hat|Puppy|PCLinuxOS)/(\\d+)\\.(\\d+)\\.(\\d+)"
|
749 |
+
},
|
750 |
+
{
|
751 |
+
"regex": "(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\\d+)\\.(\\d+)"
|
752 |
+
},
|
753 |
+
{
|
754 |
+
"regex": "(Windows|OpenBSD|FreeBSD|NetBSD|Android|WeTab)"
|
755 |
+
},
|
756 |
+
{
|
757 |
+
"regex": "(Ubuntu|Kubuntu|Arch Linux|CentOS|Slackware|Gentoo|openSUSE|SUSE|Red Hat|Fedora|PCLinuxOS|Gentoo|Mageia)"
|
758 |
+
},
|
759 |
+
{
|
760 |
+
"regex": "(Linux)/(\\d+)\\.(\\d+)"
|
761 |
+
},
|
762 |
+
{
|
763 |
+
"regex": "(Linux|BSD)"
|
764 |
+
},
|
765 |
+
{
|
766 |
+
"regex": "SunOS",
|
767 |
+
"os_replacement": "Solaris"
|
768 |
+
}
|
769 |
+
],
|
770 |
+
"device_parsers": [
|
771 |
+
{
|
772 |
+
"regex": "HTC ([A-Z][a-z0-9]+) Build",
|
773 |
+
"device_replacement": "HTC $1"
|
774 |
+
},
|
775 |
+
{
|
776 |
+
"regex": "HTC ([A-Z][a-z0-9 ]+) \\d+\\.\\d+\\.\\d+\\.\\d+",
|
777 |
+
"device_replacement": "HTC $1"
|
778 |
+
},
|
779 |
+
{
|
780 |
+
"regex": "HTC_Touch_([A-Za-z0-9]+)",
|
781 |
+
"device_replacement": "HTC Touch ($1)"
|
782 |
+
},
|
783 |
+
{
|
784 |
+
"regex": "USCCHTC(\\d+)",
|
785 |
+
"device_replacement": "HTC $1 (US Cellular)"
|
786 |
+
},
|
787 |
+
{
|
788 |
+
"regex": "Sprint APA(9292)",
|
789 |
+
"device_replacement": "HTC $1 (Sprint)"
|
790 |
+
},
|
791 |
+
{
|
792 |
+
"regex": "HTC ([A-Za-z0-9]+ [A-Z])",
|
793 |
+
"device_replacement": "HTC $1"
|
794 |
+
},
|
795 |
+
{
|
796 |
+
"regex": "HTC[-_/\\s]([A-Za-z0-9]+)",
|
797 |
+
"device_replacement": "HTC $1"
|
798 |
+
},
|
799 |
+
{
|
800 |
+
"regex": "(ADR[A-Za-z0-9]+)",
|
801 |
+
"device_replacement": "HTC $1"
|
802 |
+
},
|
803 |
+
{
|
804 |
+
"regex": "(HTC)"
|
805 |
+
},
|
806 |
+
{
|
807 |
+
"regex": "(QtCarBrowser)",
|
808 |
+
"device_replacement": "Tesla Model S"
|
809 |
+
},
|
810 |
+
{
|
811 |
+
"regex": "(SamsungSGHi560)",
|
812 |
+
"device_replacement": "Samsung SGHi560"
|
813 |
+
},
|
814 |
+
{
|
815 |
+
"regex": "SonyEricsson([A-Za-z0-9]+)/",
|
816 |
+
"device_replacement": "Ericsson $1"
|
817 |
+
},
|
818 |
+
{
|
819 |
+
"regex": "PLAYSTATION 3",
|
820 |
+
"device_replacement": "PlayStation 3"
|
821 |
+
},
|
822 |
+
{
|
823 |
+
"regex": "(PlayStation Portable)"
|
824 |
+
},
|
825 |
+
{
|
826 |
+
"regex": "(PlayStation Vita)"
|
827 |
+
},
|
828 |
+
{
|
829 |
+
"regex": "(KFOT Build)",
|
830 |
+
"device_replacement": "Kindle Fire"
|
831 |
+
},
|
832 |
+
{
|
833 |
+
"regex": "(KFTT Build)",
|
834 |
+
"device_replacement": "Kindle Fire HD"
|
835 |
+
},
|
836 |
+
{
|
837 |
+
"regex": "(KFJWI Build)",
|
838 |
+
"device_replacement": "Kindle Fire HD 8.9\" WiFi"
|
839 |
+
},
|
840 |
+
{
|
841 |
+
"regex": "(KFJWA Build)",
|
842 |
+
"device_replacement": "Kindle Fire HD 8.9\" 4G"
|
843 |
+
},
|
844 |
+
{
|
845 |
+
"regex": "(Kindle Fire)"
|
846 |
+
},
|
847 |
+
{
|
848 |
+
"regex": "(Kindle)"
|
849 |
+
},
|
850 |
+
{
|
851 |
+
"regex": "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+))?",
|
852 |
+
"device_replacement": "Kindle Fire"
|
853 |
+
},
|
854 |
+
{
|
855 |
+
"regex": "Android[\\- ][\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{2}; WOWMobile (.+) Build"
|
856 |
+
},
|
857 |
+
{
|
858 |
+
"regex": "Android[\\- ][\\d]+\\.[\\d]+\\-update1; [A-Za-z]{2}\\-[A-Za-z]{2}; (.+) Build"
|
859 |
+
},
|
860 |
+
{
|
861 |
+
"regex": "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{2}; (.+) Build"
|
862 |
+
},
|
863 |
+
{
|
864 |
+
"regex": "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+;[A-Za-z]{2}\\-[A-Za-z]{2};(.+) Build"
|
865 |
+
},
|
866 |
+
{
|
867 |
+
"regex": "Android[\\- ][\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{2}; (.+) Build"
|
868 |
+
},
|
869 |
+
{
|
870 |
+
"regex": "Android[\\- ][\\d]+\\.[\\d]+\\.[\\d]+; (.+) Build"
|
871 |
+
},
|
872 |
+
{
|
873 |
+
"regex": "Android[\\- ][\\d]+\\.[\\d]+; (.+) Build"
|
874 |
+
},
|
875 |
+
{
|
876 |
+
"regex": "NokiaN([0-9]+)",
|
877 |
+
"device_replacement": "Nokia N$1"
|
878 |
+
},
|
879 |
+
{
|
880 |
+
"regex": "NOKIA([A-Za-z0-9\\v-]+)",
|
881 |
+
"device_replacement": "Nokia $1"
|
882 |
+
},
|
883 |
+
{
|
884 |
+
"regex": "Nokia([A-Za-z0-9\\v-]+)",
|
885 |
+
"device_replacement": "Nokia $1"
|
886 |
+
},
|
887 |
+
{
|
888 |
+
"regex": "NOKIA ([A-Za-z0-9\\-]+)",
|
889 |
+
"device_replacement": "Nokia $1"
|
890 |
+
},
|
891 |
+
{
|
892 |
+
"regex": "Nokia ([A-Za-z0-9\\-]+)",
|
893 |
+
"device_replacement": "Nokia $1"
|
894 |
+
},
|
895 |
+
{
|
896 |
+
"regex": "Lumia ([A-Za-z0-9\\-]+)",
|
897 |
+
"device_replacement": "Lumia $1"
|
898 |
+
},
|
899 |
+
{
|
900 |
+
"regex": "Symbian",
|
901 |
+
"device_replacement": "Nokia"
|
902 |
+
},
|
903 |
+
{
|
904 |
+
"regex": "BB10; ([A-Za-z0-9\\- ]+)\\)",
|
905 |
+
"device_replacement": "BlackBerry $1"
|
906 |
+
},
|
907 |
+
{
|
908 |
+
"regex": "(PlayBook).+RIM Tablet OS",
|
909 |
+
"device_replacement": "BlackBerry Playbook"
|
910 |
+
},
|
911 |
+
{
|
912 |
+
"regex": "Black[Bb]erry ([0-9]+);",
|
913 |
+
"device_replacement": "BlackBerry $1"
|
914 |
+
},
|
915 |
+
{
|
916 |
+
"regex": "Black[Bb]erry([0-9]+)",
|
917 |
+
"device_replacement": "BlackBerry $1"
|
918 |
+
},
|
919 |
+
{
|
920 |
+
"regex": "Black[Bb]erry;",
|
921 |
+
"device_replacement": "BlackBerry"
|
922 |
+
},
|
923 |
+
{
|
924 |
+
"regex": "(Pre)/(\\d+)\\.(\\d+)",
|
925 |
+
"device_replacement": "Palm Pre"
|
926 |
+
},
|
927 |
+
{
|
928 |
+
"regex": "(Pixi)/(\\d+)\\.(\\d+)",
|
929 |
+
"device_replacement": "Palm Pixi"
|
930 |
+
},
|
931 |
+
{
|
932 |
+
"regex": "(Touch[Pp]ad)/(\\d+)\\.(\\d+)",
|
933 |
+
"device_replacement": "HP TouchPad"
|
934 |
+
},
|
935 |
+
{
|
936 |
+
"regex": "HPiPAQ([A-Za-z0-9]+)/(\\d+).(\\d+)",
|
937 |
+
"device_replacement": "HP iPAQ $1"
|
938 |
+
},
|
939 |
+
{
|
940 |
+
"regex": "Palm([A-Za-z0-9]+)",
|
941 |
+
"device_replacement": "Palm $1"
|
942 |
+
},
|
943 |
+
{
|
944 |
+
"regex": "Treo([A-Za-z0-9]+)",
|
945 |
+
"device_replacement": "Palm Treo $1"
|
946 |
+
},
|
947 |
+
{
|
948 |
+
"regex": "webOS.*(P160UNA)/(\\d+).(\\d+)",
|
949 |
+
"device_replacement": "HP Veer"
|
950 |
+
},
|
951 |
+
{
|
952 |
+
"regex": "(AppleTV)",
|
953 |
+
"device_replacement": "AppleTV"
|
954 |
+
},
|
955 |
+
{
|
956 |
+
"regex": "AdsBot-Google-Mobile",
|
957 |
+
"device_replacement": "Spider"
|
958 |
+
},
|
959 |
+
{
|
960 |
+
"regex": "Googlebot-Mobile/(\\d+).(\\d+)",
|
961 |
+
"device_replacement": "Spider"
|
962 |
+
},
|
963 |
+
{
|
964 |
+
"regex": "(iPad) Simulator;"
|
965 |
+
},
|
966 |
+
{
|
967 |
+
"regex": "(iPad);"
|
968 |
+
},
|
969 |
+
{
|
970 |
+
"regex": "(iPod);"
|
971 |
+
},
|
972 |
+
{
|
973 |
+
"regex": "(iPhone) Simulator;"
|
974 |
+
},
|
975 |
+
{
|
976 |
+
"regex": "(iPhone);"
|
977 |
+
},
|
978 |
+
{
|
979 |
+
"regex": "acer_([A-Za-z0-9]+)_",
|
980 |
+
"device_replacement": "Acer $1"
|
981 |
+
},
|
982 |
+
{
|
983 |
+
"regex": "acer_([A-Za-z0-9]+)_",
|
984 |
+
"device_replacement": "Acer $1"
|
985 |
+
},
|
986 |
+
{
|
987 |
+
"regex": "ALCATEL-([A-Za-z0-9]+)",
|
988 |
+
"device_replacement": "Alcatel $1"
|
989 |
+
},
|
990 |
+
{
|
991 |
+
"regex": "Alcatel-([A-Za-z0-9]+)",
|
992 |
+
"device_replacement": "Alcatel $1"
|
993 |
+
},
|
994 |
+
{
|
995 |
+
"regex": "Amoi\\-([A-Za-z0-9]+)",
|
996 |
+
"device_replacement": "Amoi $1"
|
997 |
+
},
|
998 |
+
{
|
999 |
+
"regex": "AMOI\\-([A-Za-z0-9]+)",
|
1000 |
+
"device_replacement": "Amoi $1"
|
1001 |
+
},
|
1002 |
+
{
|
1003 |
+
"regex": "Asus\\-([A-Za-z0-9]+)",
|
1004 |
+
"device_replacement": "Asus $1"
|
1005 |
+
},
|
1006 |
+
{
|
1007 |
+
"regex": "ASUS\\-([A-Za-z0-9]+)",
|
1008 |
+
"device_replacement": "Asus $1"
|
1009 |
+
},
|
1010 |
+
{
|
1011 |
+
"regex": "BIRD\\-([A-Za-z0-9]+)",
|
1012 |
+
"device_replacement": "Bird $1"
|
1013 |
+
},
|
1014 |
+
{
|
1015 |
+
"regex": "BIRD\\.([A-Za-z0-9]+)",
|
1016 |
+
"device_replacement": "Bird $1"
|
1017 |
+
},
|
1018 |
+
{
|
1019 |
+
"regex": "BIRD ([A-Za-z0-9]+)",
|
1020 |
+
"device_replacement": "Bird $1"
|
1021 |
+
},
|
1022 |
+
{
|
1023 |
+
"regex": "Dell ([A-Za-z0-9]+)",
|
1024 |
+
"device_replacement": "Dell $1"
|
1025 |
+
},
|
1026 |
+
{
|
1027 |
+
"regex": "DoCoMo/2\\.0 ([A-Za-z0-9]+)",
|
1028 |
+
"device_replacement": "DoCoMo $1"
|
1029 |
+
},
|
1030 |
+
{
|
1031 |
+
"regex": "([A-Za-z0-9]+)_W\\;FOMA",
|
1032 |
+
"device_replacement": "DoCoMo $1"
|
1033 |
+
},
|
1034 |
+
{
|
1035 |
+
"regex": "([A-Za-z0-9]+)\\;FOMA",
|
1036 |
+
"device_replacement": "DoCoMo $1"
|
1037 |
+
},
|
1038 |
+
{
|
1039 |
+
"regex": "Huawei([A-Za-z0-9]+)",
|
1040 |
+
"device_replacement": "Huawei $1"
|
1041 |
+
},
|
1042 |
+
{
|
1043 |
+
"regex": "HUAWEI-([A-Za-z0-9]+)",
|
1044 |
+
"device_replacement": "Huawei $1"
|
1045 |
+
},
|
1046 |
+
{
|
1047 |
+
"regex": "vodafone([A-Za-z0-9]+)",
|
1048 |
+
"device_replacement": "Huawei Vodafone $1"
|
1049 |
+
},
|
1050 |
+
{
|
1051 |
+
"regex": "i\\-mate ([A-Za-z0-9]+)",
|
1052 |
+
"device_replacement": "i-mate $1"
|
1053 |
+
},
|
1054 |
+
{
|
1055 |
+
"regex": "Kyocera\\-([A-Za-z0-9]+)",
|
1056 |
+
"device_replacement": "Kyocera $1"
|
1057 |
+
},
|
1058 |
+
{
|
1059 |
+
"regex": "KWC\\-([A-Za-z0-9]+)",
|
1060 |
+
"device_replacement": "Kyocera $1"
|
1061 |
+
},
|
1062 |
+
{
|
1063 |
+
"regex": "Lenovo\\-([A-Za-z0-9]+)",
|
1064 |
+
"device_replacement": "Lenovo $1"
|
1065 |
+
},
|
1066 |
+
{
|
1067 |
+
"regex": "Lenovo_([A-Za-z0-9]+)",
|
1068 |
+
"device_replacement": "Lenovo $1"
|
1069 |
+
},
|
1070 |
+
{
|
1071 |
+
"regex": "LG/([A-Za-z0-9]+)",
|
1072 |
+
"device_replacement": "LG $1"
|
1073 |
+
},
|
1074 |
+
{
|
1075 |
+
"regex": "LG-LG([A-Za-z0-9]+)",
|
1076 |
+
"device_replacement": "LG $1"
|
1077 |
+
},
|
1078 |
+
{
|
1079 |
+
"regex": "LGE-LG([A-Za-z0-9]+)",
|
1080 |
+
"device_replacement": "LG $1"
|
1081 |
+
},
|
1082 |
+
{
|
1083 |
+
"regex": "LGE VX([A-Za-z0-9]+)",
|
1084 |
+
"device_replacement": "LG $1"
|
1085 |
+
},
|
1086 |
+
{
|
1087 |
+
"regex": "LG ([A-Za-z0-9]+)",
|
1088 |
+
"device_replacement": "LG $1"
|
1089 |
+
},
|
1090 |
+
{
|
1091 |
+
"regex": "LGE LG\\-AX([A-Za-z0-9]+)",
|
1092 |
+
"device_replacement": "LG $1"
|
1093 |
+
},
|
1094 |
+
{
|
1095 |
+
"regex": "LG\\-([A-Za-z0-9]+)",
|
1096 |
+
"device_replacement": "LG $1"
|
1097 |
+
},
|
1098 |
+
{
|
1099 |
+
"regex": "LGE\\-([A-Za-z0-9]+)",
|
1100 |
+
"device_replacement": "LG $1"
|
1101 |
+
},
|
1102 |
+
{
|
1103 |
+
"regex": "LG([A-Za-z0-9]+)",
|
1104 |
+
"device_replacement": "LG $1"
|
1105 |
+
},
|
1106 |
+
{
|
1107 |
+
"regex": "(KIN)\\.One (\\d+)\\.(\\d+)",
|
1108 |
+
"device_replacement": "Microsoft $1"
|
1109 |
+
},
|
1110 |
+
{
|
1111 |
+
"regex": "(KIN)\\.Two (\\d+)\\.(\\d+)",
|
1112 |
+
"device_replacement": "Microsoft $1"
|
1113 |
+
},
|
1114 |
+
{
|
1115 |
+
"regex": "(Motorola)\\-([A-Za-z0-9]+)"
|
1116 |
+
},
|
1117 |
+
{
|
1118 |
+
"regex": "MOTO\\-([A-Za-z0-9]+)",
|
1119 |
+
"device_replacement": "Motorola $1"
|
1120 |
+
},
|
1121 |
+
{
|
1122 |
+
"regex": "MOT\\-([A-Za-z0-9]+)",
|
1123 |
+
"device_replacement": "Motorola $1"
|
1124 |
+
},
|
1125 |
+
{
|
1126 |
+
"regex": "(Nintendo WiiU)",
|
1127 |
+
"device_replacement": "Nintendo Wii U"
|
1128 |
+
},
|
1129 |
+
{
|
1130 |
+
"regex": "Nintendo (DS|3DS|DSi|Wii);",
|
1131 |
+
"device_replacement": "Nintendo $1"
|
1132 |
+
},
|
1133 |
+
{
|
1134 |
+
"regex": "Pantech([A-Za-z0-9]+)",
|
1135 |
+
"device_replacement": "Pantech $1"
|
1136 |
+
},
|
1137 |
+
{
|
1138 |
+
"regex": "Philips([A-Za-z0-9]+)",
|
1139 |
+
"device_replacement": "Philips $1"
|
1140 |
+
},
|
1141 |
+
{
|
1142 |
+
"regex": "Philips ([A-Za-z0-9]+)",
|
1143 |
+
"device_replacement": "Philips $1"
|
1144 |
+
},
|
1145 |
+
{
|
1146 |
+
"regex": "SAMSUNG-([A-Za-z0-9\\-]+)",
|
1147 |
+
"device_replacement": "Samsung $1"
|
1148 |
+
},
|
1149 |
+
{
|
1150 |
+
"regex": "SAMSUNG\\; ([A-Za-z0-9\\-]+)",
|
1151 |
+
"device_replacement": "Samsung $1"
|
1152 |
+
},
|
1153 |
+
{
|
1154 |
+
"regex": "Dreamcast",
|
1155 |
+
"device_replacement": "Sega Dreamcast"
|
1156 |
+
},
|
1157 |
+
{
|
1158 |
+
"regex": "Softbank/1\\.0/([A-Za-z0-9]+)",
|
1159 |
+
"device_replacement": "Softbank $1"
|
1160 |
+
},
|
1161 |
+
{
|
1162 |
+
"regex": "Softbank/2\\.0/([A-Za-z0-9]+)",
|
1163 |
+
"device_replacement": "Softbank $1"
|
1164 |
+
},
|
1165 |
+
{
|
1166 |
+
"regex": "(WebTV)/(\\d+).(\\d+)"
|
1167 |
+
},
|
1168 |
+
{
|
1169 |
+
"regex": "(hiptop|avantgo|plucker|xiino|blazer|elaine|up.browser|up.link|mmp|smartphone|midp|wap|vodafone|o2|pocket|mobile|pda)",
|
1170 |
+
"device_replacement": "Generic Smartphone"
|
1171 |
+
},
|
1172 |
+
{
|
1173 |
+
"regex": "^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\\-|airn|alav|asus|attw|au\\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bell|bird|bw\\-n|bw\\-u|beck|benq|bilb|blac|c55/|cdm\\-|chtm|capi|comp|cond|craw|dall|dbte|dc\\-s|dica|ds\\-d|ds12|dait|devi|dmob|doco|dopo|el49|erk0|esl8|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\\-|fly_|g\\-mo|g1 u|g560|gf\\-5|grun|gene|go.w|good|grad|hcit|hd\\-m|hd\\-p|hd\\-t|hei\\-|hp i|hpip|hs\\-c|htc |htc\\-|htca|htcg)",
|
1174 |
+
"device_replacement": "Generic Feature Phone"
|
1175 |
+
},
|
1176 |
+
{
|
1177 |
+
"regex": "^(htcp|htcs|htct|htc_|haie|hita|huaw|hutc|i\\-20|i\\-go|i\\-ma|i230|iac|iac\\-|iac/|ig01|im1k|inno|iris|jata|java|kddi|kgt|kgt/|kpt |kwc\\-|klon|lexi|lg g|lg\\-a|lg\\-b|lg\\-c|lg\\-d|lg\\-f|lg\\-g|lg\\-k|lg\\-l|lg\\-m|lg\\-o|lg\\-p|lg\\-s|lg\\-t|lg\\-u|lg\\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\\-|lge/|lynx|leno|m1\\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\\-|nem\\-|newg|neon)",
|
1178 |
+
"device_replacement": "Generic Feature Phone"
|
1179 |
+
},
|
1180 |
+
{
|
1181 |
+
"regex": "^(netf|noki|nzph|o2 x|o2\\-x|opwv|owg1|opti|oran|ot\\-s|p800|pand|pg\\-1|pg\\-2|pg\\-3|pg\\-6|pg\\-8|pg\\-c|pg13|phil|pn\\-2|pt\\-g|palm|pana|pire|pock|pose|psio|qa\\-a|qc\\-2|qc\\-3|qc\\-5|qc\\-7|qc07|qc12|qc21|qc32|qc60|qci\\-|qwap|qtek|r380|r600|raks|rim9|rove|s55/|sage|sams|sc01|sch\\-|scp\\-|sdk/|se47|sec\\-|sec0|sec1|semc|sgh\\-|shar|sie\\-|sk\\-0|sl45|slid|smb3|smt5|sp01|sph\\-|spv |spv\\-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t\\-mo|t218|t250|t600|t610|t618|tcl\\-|tdg\\-|telm|tim\\-|ts70|tsm\\-|tsm3|tsm5|tx\\-9|tagt)",
|
1182 |
+
"device_replacement": "Generic Feature Phone"
|
1183 |
+
},
|
1184 |
+
{
|
1185 |
+
"regex": "^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vite|voda|vulc|w3c |w3c\\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\\-|your|zte\\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\\-|webc|whit|wmlb|xda\\-|xda_)",
|
1186 |
+
"device_replacement": "Generic Feature Phone"
|
1187 |
+
},
|
1188 |
+
{
|
1189 |
+
"regex": "(bot|borg|google(^tv)|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast\\-webcrawler|converacrawler|dataparksearch|findlinks|crawler)",
|
1190 |
+
"device_replacement": "Spider"
|
1191 |
+
}
|
1192 |
+
]
|
1193 |
+
}
|
includes/admin/uaparser/uaparser-cli.php
ADDED
@@ -0,0 +1,279 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*!
|
4 |
+
* ua-parser-php CLI v2.1.1
|
5 |
+
*
|
6 |
+
* Copyright (c) 2012 Dave Olsen, http://dmolsen.com
|
7 |
+
* Licensed under the MIT license
|
8 |
+
*
|
9 |
+
* spyc-0.5, for loading the YAML, is licensed under the MIT license.
|
10 |
+
* Services_JSON, for loading the JSON in sub-PHP 5.2 installs, is licensed under the MIT license
|
11 |
+
*
|
12 |
+
* This is the CLI for ua-parser-php. The following commands are supported:
|
13 |
+
*
|
14 |
+
* php uaparser-cli.php
|
15 |
+
* Provides the usage information.
|
16 |
+
*
|
17 |
+
* php uaparser-cli.php [-p] [-j] "your user agent string"
|
18 |
+
* Parses a user agent string and dumps the results as a list.
|
19 |
+
* Use the -j flag to print the result as JSON.
|
20 |
+
* Use the -p flag to pretty print the JSON result when using PHP 5.4+.
|
21 |
+
*
|
22 |
+
* php uaparser-cli.php -g [-s] [-n]
|
23 |
+
* Fetches an updated YAML file for UAParser and overwrites the current JSON file.
|
24 |
+
* By default is verbose. Use -s to turn that feature off.
|
25 |
+
* By default creates a back-up. Use -n to turn that feature off.
|
26 |
+
*
|
27 |
+
* php uaparser-cli.php -c [-s] [-n]
|
28 |
+
* Converts an existing regexes.yaml file to a regexes.json file.
|
29 |
+
* By default is verbose. Use -s to turn that feature off.
|
30 |
+
* By default creates a back-up. Use -n to turn that feature off.
|
31 |
+
*
|
32 |
+
* php uaparser-cli.php -y
|
33 |
+
* Fetches an updated YAML file. If you need to add a new UA it's easier to edit
|
34 |
+
* the original YAML and then convert it. Warning: This method overwrites any
|
35 |
+
* existing regexes.yaml file.
|
36 |
+
*
|
37 |
+
* php uaparser-cli.php -l /path/to/apache/logfile
|
38 |
+
* Parses the supplied Apache log file to test UAParser.php. Saves the UA to a file
|
39 |
+
* when the UA or OS family aren't found or when the UA is listed as a generic
|
40 |
+
* smartphone or as a generic feature phone.
|
41 |
+
*
|
42 |
+
* Thanks to Marcus Bointon (https://github.com/Synchro) for getting this file started
|
43 |
+
* and adding the initial JSON parser for a UA string.
|
44 |
+
*
|
45 |
+
*/
|
46 |
+
|
47 |
+
// define the base path for the file
|
48 |
+
$basePath = dirname(__FILE__).DIRECTORY_SEPARATOR;
|
49 |
+
|
50 |
+
// address 5.1 compatibility
|
51 |
+
if (!function_exists('json_decode') || !function_exists('json_encode')) {
|
52 |
+
require_once($basePath."lib/json/jsonwrapper.php");
|
53 |
+
}
|
54 |
+
|
55 |
+
// include the YAML library
|
56 |
+
require_once($basePath."lib/spyc-0.5/spyc.php");
|
57 |
+
|
58 |
+
// include UAParser.php and make sure to turn off the CLI error
|
59 |
+
require_once($basePath."uaparser.php");
|
60 |
+
|
61 |
+
// deal with timezone issues & logging
|
62 |
+
if (!ini_get('date.timezone')) {
|
63 |
+
date_default_timezone_set(@date_default_timezone_get());
|
64 |
+
}
|
65 |
+
|
66 |
+
/*
|
67 |
+
* Gets the latest user agent. Back-ups the old version first. it will fail silently if something is wrong...
|
68 |
+
*/
|
69 |
+
function get($file,$silent,$nobackup,$basePath) {
|
70 |
+
if (ini_get('allow_url_fopen')) {
|
71 |
+
if ($data = @file_get_contents($file)) {
|
72 |
+
if (!$silent) { print "loading and converting YAML data...\n"; };
|
73 |
+
$data = Spyc::YAMLLoad($data);
|
74 |
+
$data = json_encode($data);
|
75 |
+
if (!$silent) { print "encoded as JSON...\n"; };
|
76 |
+
if (file_exists($basePath."resources/regexes.json")) {
|
77 |
+
if (!$nobackup) {
|
78 |
+
if (!$silent) { print("backing up old JSON file...\n"); }
|
79 |
+
if (!copy($basePath."resources/regexes.json", $basePath."resources/regexes.".date("Ymdhis").".json")) {
|
80 |
+
if (!$silent) { print("back-up failed...\n"); }
|
81 |
+
exit;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
}
|
85 |
+
file_put_contents($basePath."resources/regexes.json", $data);
|
86 |
+
if (!$silent) { print("saved JSON file...\n"); }
|
87 |
+
} else {
|
88 |
+
if (!$silent) { print("failed to get the file...\n"); }
|
89 |
+
}
|
90 |
+
} else {
|
91 |
+
if (!$silent) { print("ERROR: the allow_url_fopen option is not enabled in php.ini. it needs to be set to 'On' for this feature to work...\n"); }
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
/*
|
96 |
+
* Main logic for the CLI for the parser
|
97 |
+
*/
|
98 |
+
if (php_sapi_name() == 'cli') {
|
99 |
+
|
100 |
+
// define the supported argument flags
|
101 |
+
$args = getopt("gsncyl:pj:");
|
102 |
+
|
103 |
+
// process the arguments
|
104 |
+
if (isset($args["g"])) {
|
105 |
+
|
106 |
+
/* Get regexes.yaml from the repo and convert it to JSON */
|
107 |
+
|
108 |
+
// set-up some standard vars
|
109 |
+
$silent = isset($args["s"]) ? true : false;
|
110 |
+
$nobackup = isset($args["n"]) ? true : false;
|
111 |
+
|
112 |
+
// start chatty
|
113 |
+
if (!$silent) {
|
114 |
+
print "getting the YAML file from the repo...\n";
|
115 |
+
}
|
116 |
+
|
117 |
+
// get the file
|
118 |
+
get("https://raw.github.com/tobie/ua-parser/master/regexes.yaml",$silent,$nobackup,$basePath);
|
119 |
+
|
120 |
+
} else if (isset($args["c"])) {
|
121 |
+
|
122 |
+
/* Convert regexes.yaml to regexes.json */
|
123 |
+
|
124 |
+
// set-up some standard vars
|
125 |
+
$silent = isset($args["s"]) ? true : false;
|
126 |
+
$nobackup = isset($args["n"]) ? true : false;
|
127 |
+
|
128 |
+
// start chatty
|
129 |
+
if (!$silent) {
|
130 |
+
print "getting the old YAML file...\n";
|
131 |
+
}
|
132 |
+
|
133 |
+
// get the file
|
134 |
+
get($basePath."resources/regexes.yaml",$silent,$nobackup,$basePath);
|
135 |
+
|
136 |
+
} else if (isset($args["y"])) {
|
137 |
+
|
138 |
+
/* Grabs regexes.yaml from the repo and saves it */
|
139 |
+
|
140 |
+
if ($data = @file_get_contents("https://raw.github.com/tobie/ua-parser/master/regexes.yaml")) {
|
141 |
+
file_put_contents($basePath."resources/regexes.yaml", $data);
|
142 |
+
print("saved YAML file from the repo...\n");
|
143 |
+
} else {
|
144 |
+
print("failed to get the YAML file from the repo...\n");
|
145 |
+
}
|
146 |
+
|
147 |
+
} else if (isset($args["l"]) && $args["l"]) {
|
148 |
+
|
149 |
+
/* Parse the supplied Apache log file */
|
150 |
+
|
151 |
+
// load the parser
|
152 |
+
$parser = new UAParser;
|
153 |
+
|
154 |
+
// set-up some standard vars
|
155 |
+
$i = 0;
|
156 |
+
$output = "";
|
157 |
+
$saved = array();
|
158 |
+
$data = @fopen($args["l"], "r");
|
159 |
+
|
160 |
+
if ($data) {
|
161 |
+
$fp = fopen($basePath."log/results-".date("YmdHis").".txt", "w");
|
162 |
+
while (($line = fgets($data)) !== false) {
|
163 |
+
$failure = false;
|
164 |
+
$show = "";
|
165 |
+
$line = str_replace("\n","",$line);
|
166 |
+
preg_match("/^(\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) (\".*?\") (\"(.*?)\")$/", $line, $items);
|
167 |
+
$ua = (isset($items[14])) ? $items[14] : "";
|
168 |
+
if (!empty($ua) && ($ua != "-")) {
|
169 |
+
$result = $parser->parse($ua);
|
170 |
+
if (($result->ua->family == "Other") && ($result->device->family != "Spider")) {
|
171 |
+
$output = "UA Not Found: ".$ua." [".$line."]\n";
|
172 |
+
$show = "U";
|
173 |
+
} else if (($result->os->family == "Other") && ($result->device->family != "Spider")) {
|
174 |
+
$output = "OS Not Found: ".$ua." [".$line."]\n";
|
175 |
+
$show = "O";
|
176 |
+
} else if ($result->device->family == "Generic Smartphone") {
|
177 |
+
$output = "GS: ".$ua." [".$line."]\n";
|
178 |
+
$show = "GS";
|
179 |
+
} else if ($result->device->family == "Generic Feature Phone") {
|
180 |
+
$output = "GFP: ".$ua." [".$line."]\n";
|
181 |
+
$show = "GFP";
|
182 |
+
}
|
183 |
+
if ((($show == "U") || ($show == "O") || ($show == "GS") || ($show == "GFP")) && !in_array($ua,$saved)) {
|
184 |
+
fwrite($fp, $output);
|
185 |
+
$saved[] = $ua;
|
186 |
+
print $show;
|
187 |
+
} else {
|
188 |
+
$i = ($i < 20) ? $i+1 : 0;
|
189 |
+
if ($i == 0) {
|
190 |
+
print ".";
|
191 |
+
}
|
192 |
+
}
|
193 |
+
}
|
194 |
+
}
|
195 |
+
if (!feof($data)) {
|
196 |
+
print "Error: unexpected fgets() fail\n";
|
197 |
+
}
|
198 |
+
fclose($fp);
|
199 |
+
fclose($data);
|
200 |
+
print "\ncompleted the evaluation of the log file at ".$args["l"]."\n";
|
201 |
+
} else {
|
202 |
+
print "unable to read the file at the supplied path...\n";
|
203 |
+
}
|
204 |
+
|
205 |
+
} else if (isset($args["j"]) && $args["j"]) {
|
206 |
+
|
207 |
+
/* Parse the supplied UA from the command line and kick it out as JSON */
|
208 |
+
|
209 |
+
// load the parser
|
210 |
+
$parser = new UAParser;
|
211 |
+
|
212 |
+
// parse and encode the results
|
213 |
+
if (version_compare(PHP_VERSION, '5.4.0', '>=') && isset($args["p"])) {
|
214 |
+
print json_encode($parser->parse($args["j"]), JSON_PRETTY_PRINT);
|
215 |
+
} else {
|
216 |
+
print json_encode($parser->parse($args["j"]));
|
217 |
+
}
|
218 |
+
print PHP_EOL;
|
219 |
+
|
220 |
+
} else if (isset($argv[1]) && (($argv[1] != "-j") && ($argv[1] != "-p") && ($argv[1] != "-l") && ($argv[1] != "-s") && ($argv[1] != "-n"))) {
|
221 |
+
|
222 |
+
/* Parse the supplied UA from the command line and kick it out as JSON */
|
223 |
+
|
224 |
+
// load the parser
|
225 |
+
$parser = new UAParser;
|
226 |
+
|
227 |
+
// parse and print the results
|
228 |
+
$result = $parser->parse($argv[1]);
|
229 |
+
print " ua-parser results for \"".$argv[1]."\"\n";
|
230 |
+
foreach ($result as $key => $value) {
|
231 |
+
if (gettype($value) == "object") {
|
232 |
+
foreach ($value as $key2 => $value2) {
|
233 |
+
print " ".$key."->".$key2.": ".$value2."\n";
|
234 |
+
}
|
235 |
+
} else {
|
236 |
+
print " ".$key.": ".$value."\n";
|
237 |
+
}
|
238 |
+
}
|
239 |
+
|
240 |
+
} else {
|
241 |
+
|
242 |
+
/* Print usage information */
|
243 |
+
|
244 |
+
print "\n";
|
245 |
+
print "Usage:\n";
|
246 |
+
print "\n";
|
247 |
+
print " php uaparser-cli.php [-p] [-j] \"your user agent string\"\n";
|
248 |
+
print " Parses a user agent string and dumps the results as a list.\n";
|
249 |
+
print " Use the -j flag to print the result as JSON.\n";
|
250 |
+
print " Use the -p flag to pretty print the JSON result when using PHP 5.4+.\n";
|
251 |
+
print "\n";
|
252 |
+
print " php uaparser-cli.php -g [-s] [-n]\n";
|
253 |
+
print " Fetches an updated YAML file for ua-parser and overwrites the current JSON file.\n";
|
254 |
+
print " By default is verbose. Use -s to turn that feature off.\n";
|
255 |
+
print " By default creates a back-up. Use -n to turn that feature off.\n";
|
256 |
+
print "\n";
|
257 |
+
print " php uaparser-cli.php -c [-s] [-n]\n";
|
258 |
+
print " Converts an existing regexes.yaml file to a regexes.json file.\n";
|
259 |
+
print " By default is verbose. Use -s to turn that feature off.\n";
|
260 |
+
print " By default creates a back-up. Use -n to turn that feature off.\n";
|
261 |
+
print "\n";
|
262 |
+
print " php uaparser-cli.php -y\n";
|
263 |
+
print " Fetches an updated YAML file. If you need to add a new UA it's easier to edit\n";
|
264 |
+
print " the original YAML and then convert it. Warning: This method overwrites any\n";
|
265 |
+
print " existing regexes.yaml file.\n";
|
266 |
+
print "\n";
|
267 |
+
print " php uaparser-cli.php -l \"/path/to/apache/logfile\"\n";
|
268 |
+
print " Parses the supplied Apache log file to test UAParser.php. Saves the UA to a file\n";
|
269 |
+
print " when the UA or OS family aren't found or when the UA is listed as a generic\n";
|
270 |
+
print " smartphone or as a generic feature phone.\n";
|
271 |
+
print "\n";
|
272 |
+
|
273 |
+
}
|
274 |
+
|
275 |
+
} else {
|
276 |
+
|
277 |
+
print "You must run this file from the command line.";
|
278 |
+
|
279 |
+
}
|
includes/admin/uaparser/uaparser-test.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*!
|
4 |
+
* ua-parser-php Test Suite v2.1.1
|
5 |
+
*
|
6 |
+
* Copyright (c) 2012 Dave Olsen, http://dmolsen.com
|
7 |
+
* Licensed under the MIT license
|
8 |
+
*
|
9 |
+
* spyc-0.5, for loading the YAML, is licensed under the MIT license.
|
10 |
+
*
|
11 |
+
* This is the test suit for ua-parser-php to make sure it matches
|
12 |
+
* the standards set forth for ua-parser libraries.
|
13 |
+
*
|
14 |
+
* IMPORTANT: This test suite skips the Chrome Frame tests because
|
15 |
+
* the PHP lib doesn't support that feature.
|
16 |
+
*
|
17 |
+
*/
|
18 |
+
|
19 |
+
// define the base path for the file
|
20 |
+
$basePath = dirname(__FILE__).DIRECTORY_SEPARATOR;
|
21 |
+
|
22 |
+
// include the YAML library
|
23 |
+
require_once($basePath."lib/spyc-0.5/spyc.php");
|
24 |
+
|
25 |
+
// include UAParser.php
|
26 |
+
require_once($basePath."uaparser.php");
|
27 |
+
|
28 |
+
// set-up the parser
|
29 |
+
$parser = new UAParser;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* assert that the actual result and the expected result match
|
33 |
+
* NOTE: the lib calls for certain attributes to be set to null but the test cases are empty strings
|
34 |
+
* @param any the actual result of the parsing
|
35 |
+
* @param any the expected result of the test
|
36 |
+
* @return boolean the result of the test
|
37 |
+
*/
|
38 |
+
function assertEqual($actual,$expected) {
|
39 |
+
$actual = ($actual == null) ? '' : $actual;
|
40 |
+
$result = ($actual === $expected) ? true : false;
|
41 |
+
return $result;
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* reports the mismatch between a test and what was returned from uaparser.php
|
46 |
+
* @param object the result of parsing the supplied test UA
|
47 |
+
* @param array the test case properties
|
48 |
+
* @param string the name of the test file
|
49 |
+
* @return string error report for the failing test
|
50 |
+
*/
|
51 |
+
function reportMismatch($obj,$tc,$tf) {
|
52 |
+
if ($tf == "test_device") {
|
53 |
+
$info = "mismatch: got d: ".$obj->device->family." and expected d: ".$tc['family'];
|
54 |
+
} else if (($tf == "test_user_agent_parser_os") || ($tf == "additional_os_tests")) {
|
55 |
+
$info = "mismatch: got f: ".$obj->os->family." ma: ".$obj->os->major." mi: ".$obj->os->minor." p: ".$obj->os->patch." pm: ".$obj->os->patch_minor." expected f: ".$tc['family']." ma: ".$tc['major']." mi: ".$tc['minor']." p: ".$tc['patch']." pm: ".$tc['patch_minor'];
|
56 |
+
} else {
|
57 |
+
$info = "mismatch: got f: ".$obj->ua->family." ma: ".$obj->ua->major." mi: ".$obj->ua->minor." p: ".$obj->ua->patch." expected f: ".$tc['family']." ma: ".$tc['major']." mi: ".$tc['minor']." p: ".$tc['patch'];
|
58 |
+
}
|
59 |
+
print "\n ".$info;
|
60 |
+
print "\n the mismatched ua: ".$tc['user_agent_string'];
|
61 |
+
print "\n";
|
62 |
+
}
|
63 |
+
|
64 |
+
/*
|
65 |
+
* Main logic for the test suite
|
66 |
+
*/
|
67 |
+
|
68 |
+
if (php_sapi_name() == "cli") {
|
69 |
+
|
70 |
+
if (!is_dir("../test_resources")) {
|
71 |
+
print "ERROR: the full ua-parser project needs to be loaded for the test suite to work. sorry.\n";
|
72 |
+
exit;
|
73 |
+
}
|
74 |
+
|
75 |
+
// test files and properties normally in them
|
76 |
+
$test_files = array("test_user_agent_parser","test_user_agent_parser_os","additional_os_tests","test_device","firefox_user_agent_strings");
|
77 |
+
$test_props = array("family", "major", "minor", "patch", "patch_minor");
|
78 |
+
$test_types = array("test_device" => "device", "test_user_agent_parser_os" => "os", "additional_os_tests" => "os", "test_user_agent_parser" => "ua", "firefox_user_agent_strings" => "ua");
|
79 |
+
|
80 |
+
foreach($test_files as $test_file) {
|
81 |
+
print "\n\nrunning uaparser.php against ".$test_file.".yaml...\n";
|
82 |
+
$data = Spyc::YAMLLoad($basePath."../test_resources/".$test_file.".yaml");
|
83 |
+
foreach($data["test_cases"] as $test_case) {
|
84 |
+
if (!isset($test_case["js_ua"])) {
|
85 |
+
$bool = true;
|
86 |
+
$result = $parser->parse($test_case["user_agent_string"]);
|
87 |
+
foreach ($test_props as $test_prop) {
|
88 |
+
if ($bool) {
|
89 |
+
$bool = isset($test_case[$test_prop]) ? assertEqual($result->$test_types[$test_file]->$test_prop,$test_case[$test_prop]) : $bool;
|
90 |
+
}
|
91 |
+
}
|
92 |
+
if (!$bool) {
|
93 |
+
reportMismatch($result,$test_case,$test_file);
|
94 |
+
} else {
|
95 |
+
print ".";
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
print "\n\ndone testing...\n";
|
102 |
+
} else {
|
103 |
+
print "You must run this file from the command line.";
|
104 |
+
}
|
includes/admin/uaparser/uaparser.php
ADDED
@@ -0,0 +1,303 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*!
|
4 |
+
* ua-parser-php v2.1.1
|
5 |
+
*
|
6 |
+
* Copyright (c) 2011-2012 Dave Olsen, http://dmolsen.com
|
7 |
+
* Licensed under the MIT license
|
8 |
+
*
|
9 |
+
* ua-parser-php is the PHP library for the ua-parser project. Learn more about the ua-parser project at:
|
10 |
+
*
|
11 |
+
* https://github.com/tobie/ua-parser
|
12 |
+
*
|
13 |
+
* The user agents data from the ua-parser project is licensed under the Apache license.
|
14 |
+
* spyc-0.5, for loading the YAML, is licensed under the MIT license.
|
15 |
+
* Services_JSON, for loading the JSON in sub-PHP 5.2 installs, is licensed under the MIT license
|
16 |
+
* The initial list of generic feature phones & smartphones came from Mobile Web OSP under the MIT license
|
17 |
+
* The initial list of spiders was taken from Yiibu's profile project under the MIT license.
|
18 |
+
*
|
19 |
+
* Many thanks to the following major contributors:
|
20 |
+
*
|
21 |
+
* - Bryan Shelton
|
22 |
+
* - Michael Bond
|
23 |
+
* - @rjd22 (https://github.com/rjd22)
|
24 |
+
* - Timo Tijhof (https://github.com/Krinkle)
|
25 |
+
* - Marcus Bointon (https://github.com/Synchro)
|
26 |
+
* - Ryan Parman (https://github.com/skyzyx)
|
27 |
+
* - Pravin Dahal (https://github.com/pravindahal)
|
28 |
+
*/
|
29 |
+
|
30 |
+
// address 5.1 compatibility
|
31 |
+
if (!function_exists('json_decode') || !function_exists('json_encode')) {
|
32 |
+
require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'lib/json/jsonwrapper.php');
|
33 |
+
}
|
34 |
+
|
35 |
+
class UAParser {
|
36 |
+
|
37 |
+
protected $regexes;
|
38 |
+
protected $log = false;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Start up the parser by importing the json file to $this->regexes
|
42 |
+
*/
|
43 |
+
public function __construct($customRegexesFile = null) {
|
44 |
+
|
45 |
+
$regexesFile = ($customRegexesFile !== null) ? $customRegexesFile : dirname(__FILE__).DIRECTORY_SEPARATOR.'resources/regexes.json';
|
46 |
+
if (file_exists($regexesFile)) {
|
47 |
+
$this->regexes = json_decode(file_get_contents($regexesFile));
|
48 |
+
} else {
|
49 |
+
$title = 'Error loading ua-parser';
|
50 |
+
if ($customRegexesFile !== null) {
|
51 |
+
$message = 'ua-parser can\'t find the custom regexes file you supplied ('.$customRegexesFile.'). Please make sure you have the correct path.';
|
52 |
+
$instruction1 = '';
|
53 |
+
$instruction2 = '';
|
54 |
+
} else {
|
55 |
+
$message = 'Please download the regexes.json file before using uaparser.php. You can type the following at the command line to download the latest version: ';
|
56 |
+
$instruction1 = '%: cd /path/to/UAParser/';
|
57 |
+
$instruction2 = '%: php uaparser-cli.php -g';
|
58 |
+
}
|
59 |
+
|
60 |
+
if (php_sapi_name() == 'cli') {
|
61 |
+
print "\n".$title."\n";
|
62 |
+
print $message."\n\n";
|
63 |
+
print " ".$instruction2."\n\n";
|
64 |
+
} else {
|
65 |
+
print '<html><head><title>'.$title.'</title></head><body>';
|
66 |
+
print '<h1>'.$title.'</h1>';
|
67 |
+
print '<p>'.$message.'</p>';
|
68 |
+
print '<blockquote>';
|
69 |
+
print '<code>'.$instruction1.'</code><br>';
|
70 |
+
print '<code>'.$instruction2.'</code>';
|
71 |
+
print '</blockquote>';
|
72 |
+
print '</body></html>';
|
73 |
+
}
|
74 |
+
|
75 |
+
exit;
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Sets up some standard variables as well as starts the user agent parsing process
|
81 |
+
* @param string a user agent string to test, defaults to an empty string
|
82 |
+
* @return object the result of the user agent parsing
|
83 |
+
*/
|
84 |
+
public function parse($ua = '') {
|
85 |
+
|
86 |
+
// build the default obj that will be returned
|
87 |
+
$result = (object) array(
|
88 |
+
'ua' => (object) array(),
|
89 |
+
'os' => (object) array(),
|
90 |
+
'device' => (object) array(),
|
91 |
+
'toFullString' => '',
|
92 |
+
'uaOriginal' => $ua
|
93 |
+
);
|
94 |
+
|
95 |
+
// figure out the ua, os, and device properties if possible
|
96 |
+
$result->ua = $this->uaParse($ua);
|
97 |
+
$result->os = $this->osParse($ua);
|
98 |
+
$result->device = $this->deviceParse($ua);
|
99 |
+
|
100 |
+
// create a full string version based on the ua and os objects
|
101 |
+
$result->toFullString = $this->toFullString($result->ua, $result->os);
|
102 |
+
|
103 |
+
// log the results when testing
|
104 |
+
if ($this->log) {
|
105 |
+
$this->log($result);
|
106 |
+
}
|
107 |
+
|
108 |
+
return $result;
|
109 |
+
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Attempts to see if the user agent matches a user_agents_parsers regex from regexes.json
|
114 |
+
* @param string a user agent string to test
|
115 |
+
* @return object the result of the user agent parsing
|
116 |
+
*/
|
117 |
+
public function uaParse($uaString = '') {
|
118 |
+
|
119 |
+
// build the default obj that will be returned
|
120 |
+
$ua = (object) array(
|
121 |
+
'family' => 'Other',
|
122 |
+
'major' => null,
|
123 |
+
'minor' => null,
|
124 |
+
'patch' => null,
|
125 |
+
'toString' => '',
|
126 |
+
'toVersionString' => ''
|
127 |
+
);
|
128 |
+
|
129 |
+
// run the regexes to match things up
|
130 |
+
$uaRegexes = $this->regexes->user_agent_parsers;
|
131 |
+
foreach ($uaRegexes as $uaRegex) {
|
132 |
+
|
133 |
+
// tests the supplied regex against the user agent
|
134 |
+
if (preg_match('/'.str_replace('/','\/',str_replace('\/','/',$uaRegex->regex)).'/i',$uaString,$matches)) {
|
135 |
+
|
136 |
+
// Make sure matches are at least set to null or Other
|
137 |
+
if (!isset($matches[1])) { $matches[1] = 'Other'; }
|
138 |
+
if (!isset($matches[2])) { $matches[2] = null; }
|
139 |
+
if (!isset($matches[3])) { $matches[3] = null; }
|
140 |
+
if (!isset($matches[4])) { $matches[4] = null; }
|
141 |
+
|
142 |
+
// ua name
|
143 |
+
$ua->family = isset($uaRegex->family_replacement) ? str_replace('$1',$matches[1],$uaRegex->family_replacement) : $matches[1];
|
144 |
+
|
145 |
+
// version properties
|
146 |
+
$ua->major = isset($uaRegex->v1_replacement) ? $uaRegex->v1_replacement : $matches[2];
|
147 |
+
$ua->minor = isset($uaRegex->v2_replacement) ? $uaRegex->v2_replacement : $matches[3];
|
148 |
+
$ua->patch = isset($uaRegex->v3_replacement) ? $uaRegex->v3_replacement : $matches[4];
|
149 |
+
|
150 |
+
// extra strings
|
151 |
+
$ua->toString = $this->toString($ua);
|
152 |
+
$ua->toVersionString = $this->toVersionString($ua);
|
153 |
+
|
154 |
+
return $ua;
|
155 |
+
}
|
156 |
+
|
157 |
+
}
|
158 |
+
|
159 |
+
return $ua;
|
160 |
+
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Attempts to see if the user agent matches an os_parsers regex from regexes.json
|
165 |
+
* @param string a user agent string to test
|
166 |
+
* @return object the result of the os parsing
|
167 |
+
*/
|
168 |
+
public function osParse($uaString = '') {
|
169 |
+
|
170 |
+
// build the default obj that will be returned
|
171 |
+
$os = (object) array(
|
172 |
+
'family' => 'Other',
|
173 |
+
'major' => null,
|
174 |
+
'minor' => null,
|
175 |
+
'patch' => null,
|
176 |
+
'patch_minor' => null,
|
177 |
+
'toString' => '',
|
178 |
+
'toVersionString' => ''
|
179 |
+
);
|
180 |
+
|
181 |
+
// run the regexes to match things up
|
182 |
+
$osRegexes = $this->regexes->os_parsers;
|
183 |
+
foreach ($osRegexes as $osRegex) {
|
184 |
+
|
185 |
+
if (preg_match('/'.str_replace('/','\/',str_replace('\/','/',$osRegex->regex)).'/i',$uaString,$matches)) {
|
186 |
+
|
187 |
+
// Make sure matches are at least set to null or Other
|
188 |
+
if (!isset($matches[1])) { $matches[1] = 'Other'; }
|
189 |
+
if (!isset($matches[2])) { $matches[2] = null; }
|
190 |
+
if (!isset($matches[3])) { $matches[3] = null; }
|
191 |
+
if (!isset($matches[4])) { $matches[4] = null; }
|
192 |
+
if (!isset($matches[5])) { $matches[5] = null; }
|
193 |
+
|
194 |
+
// os name
|
195 |
+
$os->family = isset($osRegex->os_replacement) ? $osRegex->os_replacement : $matches[1];
|
196 |
+
|
197 |
+
// version properties
|
198 |
+
$os->major = isset($osRegex->os_v1_replacement) ? $osRegex->os_v1_replacement : $matches[2];
|
199 |
+
$os->minor = isset($osRegex->os_v2_replacement) ? $osRegex->os_v2_replacement : $matches[3];
|
200 |
+
$os->patch = isset($osRegex->os_v3_replacement) ? $osRegex->os_v3_replacement : $matches[4];
|
201 |
+
$os->patch_minor = isset($osRegex->os_v4_replacement) ? $osRegex->os_v4_replacement : $matches[5];
|
202 |
+
|
203 |
+
// extra strings
|
204 |
+
$os->toString = $this->toString($os);
|
205 |
+
$os->toVersionString = $this->toVersionString($os);
|
206 |
+
|
207 |
+
return $os;
|
208 |
+
}
|
209 |
+
|
210 |
+
}
|
211 |
+
|
212 |
+
return $os;
|
213 |
+
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Attempts to see if the user agent matches a device_parsers regex from regexes.json
|
218 |
+
* @param string a user agent string to test
|
219 |
+
* @return object the result of the device parsing
|
220 |
+
*/
|
221 |
+
public function deviceParse($uaString = '') {
|
222 |
+
|
223 |
+
// build the default obj that will be returned
|
224 |
+
$device = (object) array(
|
225 |
+
'family' => 'Other'
|
226 |
+
);
|
227 |
+
|
228 |
+
// run the regexes to match things up
|
229 |
+
$deviceRegexes = $this->regexes->device_parsers;
|
230 |
+
foreach ($deviceRegexes as $deviceRegex) {
|
231 |
+
|
232 |
+
if (preg_match('/'.str_replace('/','\/',str_replace('\/','/',$deviceRegex->regex)).'/i',$uaString,$matches)) {
|
233 |
+
|
234 |
+
// Make sure matches are at least set to null or Other
|
235 |
+
if (!isset($matches[1])) { $matches[1] = 'Other'; }
|
236 |
+
|
237 |
+
// device name
|
238 |
+
$device->family = isset($deviceRegex->device_replacement) ? str_replace('$1',str_replace("_"," ",$matches[1]),$deviceRegex->device_replacement) : str_replace("_"," ",$matches[1]);
|
239 |
+
|
240 |
+
return $device;
|
241 |
+
|
242 |
+
}
|
243 |
+
|
244 |
+
}
|
245 |
+
|
246 |
+
return $device;
|
247 |
+
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Returns a string consisting of the family and full version number based on the provided type
|
252 |
+
* @param object the object (ua or os) to be used
|
253 |
+
* @return string the result of combining family and version
|
254 |
+
*/
|
255 |
+
public function toString($obj) {
|
256 |
+
|
257 |
+
$versionString = $this->toVersionString($obj);
|
258 |
+
$string = !empty($versionString) ? $obj->family.' '.$versionString : $obj->family;
|
259 |
+
|
260 |
+
return $string;
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Returns a string consisting of just the full version number based on the provided type
|
265 |
+
* @param object the obj that contains version number bits
|
266 |
+
* @return string the result of combining the version number bits together
|
267 |
+
*/
|
268 |
+
public function toVersionString($obj) {
|
269 |
+
|
270 |
+
$versionString = isset($obj->major) ? $obj->major : '';
|
271 |
+
$versionString = isset($obj->minor) ? $versionString.'.'.$obj->minor : $versionString;
|
272 |
+
$versionString = isset($obj->patch) ? $versionString.'.'.$obj->patch : $versionString;
|
273 |
+
$versionString = isset($obj->patch_minor) ? $versionString.'.'.$obj->patch_minor : $versionString;
|
274 |
+
|
275 |
+
return $versionString;
|
276 |
+
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Returns a string consistig of the family and full version number for both the browser and os
|
281 |
+
* @param object the ua object
|
282 |
+
* @param object the os object
|
283 |
+
* @return string the result of combining family and version
|
284 |
+
*/
|
285 |
+
public function toFullString($ua,$os) {
|
286 |
+
|
287 |
+
$fullString = $this->toString($ua).'/'.$this->toString($os);
|
288 |
+
|
289 |
+
return $fullString;
|
290 |
+
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Logs the user agent info
|
295 |
+
*/
|
296 |
+
protected function log($data) {
|
297 |
+
$jsonData = json_encode($data);
|
298 |
+
$fp = fopen(dirname(__FILE__).DIRECTORY_SEPARATOR.'log/user_agents.log', 'a');
|
299 |
+
fwrite($fp, $jsonData."\r\n");
|
300 |
+
fclose($fp);
|
301 |
+
}
|
302 |
+
|
303 |
+
}
|
includes/class-dlm-ajax-handler.php
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* WP_DLM_Ajax_Handler class.
|
7 |
+
*/
|
8 |
+
class WP_DLM_Ajax_Handler {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* __construct function.
|
12 |
+
*
|
13 |
+
* @access public
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
public function __construct() {
|
17 |
+
add_action( 'wp_ajax_download_monitor_remove_file', array( $this, 'remove_file' ) );
|
18 |
+
add_action( 'wp_ajax_download_monitor_add_file', array( $this, 'add_file' ) );
|
19 |
+
add_action( 'wp_ajax_download_monitor_list_files', array( $this, 'list_files' ) );
|
20 |
+
add_action( 'wp_ajax_download_monitor_insert_panel_upload', array( $this, 'insert_panel_upload' ) );
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* insert_panel_upload function.
|
25 |
+
*
|
26 |
+
* @access public
|
27 |
+
* @return void
|
28 |
+
*/
|
29 |
+
public function insert_panel_upload() {
|
30 |
+
|
31 |
+
check_ajax_referer( 'file-upload' );
|
32 |
+
|
33 |
+
$status = wp_handle_upload( $_FILES['async-upload'], array( 'test_form' => false ) );
|
34 |
+
|
35 |
+
echo $status['url'];
|
36 |
+
|
37 |
+
die();
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* remove_file function.
|
42 |
+
*
|
43 |
+
* @access public
|
44 |
+
* @return void
|
45 |
+
*/
|
46 |
+
public function remove_file() {
|
47 |
+
|
48 |
+
check_ajax_referer( 'remove-file', 'security' );
|
49 |
+
|
50 |
+
$file = get_post( intval( $_POST['file_id'] ) );
|
51 |
+
|
52 |
+
if ( $file && $file->post_type == "dlm_download_version" )
|
53 |
+
wp_delete_post( $file->ID );
|
54 |
+
|
55 |
+
die();
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* add_file function.
|
60 |
+
*
|
61 |
+
* @access public
|
62 |
+
* @return void
|
63 |
+
*/
|
64 |
+
public function add_file() {
|
65 |
+
|
66 |
+
check_ajax_referer( 'add-file', 'security' );
|
67 |
+
|
68 |
+
$post_id = intval( $_POST['post_id'] );
|
69 |
+
$size = intval( $_POST['size'] );
|
70 |
+
|
71 |
+
$file = array(
|
72 |
+
'post_title' => 'Download #' . $post_id . ' File Version',
|
73 |
+
'post_content' => '',
|
74 |
+
'post_status' => 'publish',
|
75 |
+
'post_author' => get_current_user_id(),
|
76 |
+
'post_parent' => $post_id,
|
77 |
+
'post_type' => 'dlm_download_version'
|
78 |
+
);
|
79 |
+
|
80 |
+
$file_id = wp_insert_post( $file );
|
81 |
+
$i = $size;
|
82 |
+
$file_version = '';
|
83 |
+
$file_post_date = current_time( 'mysql' );
|
84 |
+
$file_download_count = 0;
|
85 |
+
$file_urls = array();
|
86 |
+
|
87 |
+
include( 'admin/html-downloadable-file-version.php' );
|
88 |
+
|
89 |
+
die();
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* list_files function.
|
94 |
+
*
|
95 |
+
* @access public
|
96 |
+
* @return void
|
97 |
+
*/
|
98 |
+
public function list_files() {
|
99 |
+
global $download_monitor;
|
100 |
+
|
101 |
+
check_ajax_referer( 'list-files', 'security' );
|
102 |
+
|
103 |
+
if ( ! current_user_can('manage_downloads') ) return false;
|
104 |
+
|
105 |
+
$path = esc_attr( stripslashes( $_POST['path'] ) );
|
106 |
+
|
107 |
+
if ( $path ) {
|
108 |
+
$files = $download_monitor->list_files( $path );
|
109 |
+
|
110 |
+
foreach( $files as $found_file ) {
|
111 |
+
|
112 |
+
$file = pathinfo( $found_file['path'] );
|
113 |
+
|
114 |
+
if ( $found_file['type'] == 'folder' ) {
|
115 |
+
|
116 |
+
echo '<li><a href="#" class="folder" data-path="' . trailingslashit( $file['dirname'] ) . $file['basename'] . '">' . $file['basename'] . '</a></li>';
|
117 |
+
|
118 |
+
} else {
|
119 |
+
|
120 |
+
$filename = $file['basename'];
|
121 |
+
$extension = ( empty( $file['extension'] ) ) ? '' : $file['extension'];
|
122 |
+
|
123 |
+
if ( substr( $filename, 0, 1 ) == '.' ) continue; // Ignore files starting with . like htaccess
|
124 |
+
if ( in_array( $extension, array( '', 'php', 'html', 'htm', 'tmp' ) ) ) continue; // Ignored file types
|
125 |
+
|
126 |
+
echo '<li><a href="#" class="file filetype-' . sanitize_title( $extension ) . '" data-path="' . trailingslashit( $file['dirname'] ) . $file['basename'] . '">' . $file['basename'] . '</a></li>';
|
127 |
+
|
128 |
+
}
|
129 |
+
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
die();
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
new WP_DLM_Ajax_Handler();
|
includes/class-dlm-download-handler.php
ADDED
@@ -0,0 +1,331 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* DLM_Download_Handler class.
|
7 |
+
*/
|
8 |
+
class DLM_Download_Handler {
|
9 |
+
|
10 |
+
private $endpoint;
|
11 |
+
private $ep_value;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* __construct function.
|
15 |
+
*
|
16 |
+
* @access public
|
17 |
+
* @return void
|
18 |
+
*/
|
19 |
+
public function __construct() {
|
20 |
+
$this->endpoint = ( $endpoint = get_option( 'dlm_download_endpoint' ) ) ? $endpoint : 'download';
|
21 |
+
$this->ep_value = ( $ep_value = get_option( 'dlm_download_endpoint_value' ) ) ? $ep_value : 'ID';
|
22 |
+
|
23 |
+
add_filter( 'query_vars', array( $this, 'add_query_vars'), 0 );
|
24 |
+
add_action( 'init', array( $this, 'add_endpoint'), 0 );
|
25 |
+
add_action( 'parse_request', array( $this, 'handler'), 0 );
|
26 |
+
add_action( 'dlm_can_download', array( $this, 'check_access' ), 10, 2 );
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Check access (hooked into dlm_can_download) checks if the download is members only and enfoces log in.
|
31 |
+
*
|
32 |
+
* Other plugins can use the 'dlm_can_download' filter directly to change access rights.
|
33 |
+
*
|
34 |
+
* @access public
|
35 |
+
* @param mixed $download
|
36 |
+
* @return void
|
37 |
+
*/
|
38 |
+
public function check_access( $can_download, $download ) {
|
39 |
+
if ( $download->is_members_only() && ! is_user_logged_in() )
|
40 |
+
$can_download = false;
|
41 |
+
|
42 |
+
return $can_download;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* add_query_vars function.
|
47 |
+
*
|
48 |
+
* @access public
|
49 |
+
* @return void
|
50 |
+
*/
|
51 |
+
public function add_query_vars( $vars ) {
|
52 |
+
$vars[] = $this->endpoint;
|
53 |
+
return $vars;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* add_endpoint function.
|
58 |
+
*
|
59 |
+
* @access public
|
60 |
+
* @return void
|
61 |
+
*/
|
62 |
+
public function add_endpoint() {
|
63 |
+
add_rewrite_endpoint( $this->endpoint, EP_ALL );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Listen for download requets and trigger downloading.
|
68 |
+
*
|
69 |
+
* @access public
|
70 |
+
* @return void
|
71 |
+
*/
|
72 |
+
public function handler() {
|
73 |
+
global $wp, $wpdb;
|
74 |
+
|
75 |
+
if ( ! empty( $_GET[ $this->endpoint ] ) )
|
76 |
+
$wp->query_vars[ $this->endpoint ] = $_GET[ $this->endpoint ];
|
77 |
+
|
78 |
+
if ( ! empty( $wp->query_vars[ $this->endpoint ] ) ) {
|
79 |
+
|
80 |
+
// Get ID of download
|
81 |
+
$raw_id = sanitize_title( stripslashes( $wp->query_vars[ $this->endpoint ] ) );
|
82 |
+
|
83 |
+
// Find real ID
|
84 |
+
switch ( $this->ep_value ) {
|
85 |
+
case 'slug' :
|
86 |
+
$download_id = absint( $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_name = '%s' AND post_type = 'dlm_download';", $raw_id ) ) );
|
87 |
+
break;
|
88 |
+
default :
|
89 |
+
$download_id = absint( $raw_id );
|
90 |
+
break;
|
91 |
+
}
|
92 |
+
|
93 |
+
if ( $download_id > 0 )
|
94 |
+
$download = new DLM_Download( $download_id );
|
95 |
+
else
|
96 |
+
$download = null;
|
97 |
+
|
98 |
+
// Handle version (if set)
|
99 |
+
$version_id = '';
|
100 |
+
|
101 |
+
if ( ! empty( $_GET['version'] ) ) {
|
102 |
+
$version_id = $download->get_version_id( $_GET['version'] );
|
103 |
+
}
|
104 |
+
|
105 |
+
if ( ! empty( $_GET['v'] ) ) {
|
106 |
+
$version_id = absint( $_GET['v'] );
|
107 |
+
}
|
108 |
+
|
109 |
+
if ( $version_id ) {
|
110 |
+
$download->set_version( $version_id );
|
111 |
+
}
|
112 |
+
|
113 |
+
// Action on found download
|
114 |
+
if ( ! is_null( $download ) && $download->exists() )
|
115 |
+
$this->trigger( $download, $version_id );
|
116 |
+
|
117 |
+
elseif ( $redirect = apply_filters( 'dlm_404_redirect', false ) )
|
118 |
+
wp_redirect( $redirect );
|
119 |
+
|
120 |
+
else
|
121 |
+
wp_die( __( 'Download does not exist.', 'download_monitor' ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage →', 'download_monitor' ) . '</a>', __( 'Download Error', 'download_monitor' ) );
|
122 |
+
|
123 |
+
die('1');
|
124 |
+
}
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* trigger function.
|
129 |
+
*
|
130 |
+
* @access private
|
131 |
+
* @param mixed $download
|
132 |
+
* @return void
|
133 |
+
*/
|
134 |
+
private function trigger( $download ) {
|
135 |
+
|
136 |
+
$version = $download->get_file_version();
|
137 |
+
$file_paths = $version->mirrors;
|
138 |
+
|
139 |
+
if ( empty( $file_paths ) )
|
140 |
+
wp_die( __( 'No file paths defined.', 'download_monitor' ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage →', 'download_monitor' ) . '</a>', __( 'Download Error', 'download_monitor' ) );
|
141 |
+
|
142 |
+
$file_path = $file_paths[ array_rand( $file_paths ) ];
|
143 |
+
|
144 |
+
if ( ! $file_path )
|
145 |
+
wp_die( __( 'No file paths defined.', 'download_monitor' ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage →', 'download_monitor' ) . '</a>', __( 'Download Error', 'download_monitor' ) );
|
146 |
+
|
147 |
+
// Check Access
|
148 |
+
if ( ! apply_filters( 'dlm_can_download', true, $download, $version ) ) {
|
149 |
+
|
150 |
+
if ( $redirect = apply_filters( 'dlm_access_denied_redirect', false ) )
|
151 |
+
wp_redirect( $redirect );
|
152 |
+
|
153 |
+
else
|
154 |
+
wp_die( __( 'You do not have permission to access this download.', 'download_monitor' ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage →', 'download_monitor' ) . '</a>', __( 'Download Error', 'download_monitor' ) );
|
155 |
+
|
156 |
+
exit;
|
157 |
+
}
|
158 |
+
|
159 |
+
// Log Hit
|
160 |
+
$version->increase_download_count();
|
161 |
+
|
162 |
+
// Trigger Download Action
|
163 |
+
do_action( 'dlm_downloading', $download, $version );
|
164 |
+
|
165 |
+
// Redirect to the file...
|
166 |
+
if ( apply_filters( 'dlm_do_not_force', false, $download, $version ) ) {
|
167 |
+
if ( function_exists( 'dlm_create_log' ) )
|
168 |
+
dlm_create_log( 'download', 'redirected', __( 'Redirected to file', 'download_monitor' ), $download, $version );
|
169 |
+
|
170 |
+
header( 'Location: ' . $file_path );
|
171 |
+
exit;
|
172 |
+
}
|
173 |
+
|
174 |
+
// ...or serve it
|
175 |
+
if ( ! is_multisite() ) {
|
176 |
+
|
177 |
+
$file_path = str_replace( site_url( '/', 'https' ), ABSPATH, $file_path );
|
178 |
+
$file_path = str_replace( site_url( '/', 'http' ), ABSPATH, $file_path );
|
179 |
+
|
180 |
+
} else {
|
181 |
+
|
182 |
+
// Try to replace network url
|
183 |
+
$file_path = str_replace( network_admin_url( '/', 'https' ), ABSPATH, $file_path );
|
184 |
+
$file_path = str_replace( network_admin_url( '/', 'http' ), ABSPATH, $file_path );
|
185 |
+
|
186 |
+
// Try to replace upload URL
|
187 |
+
$upload_dir = wp_upload_dir();
|
188 |
+
$file_path = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $file_path );
|
189 |
+
}
|
190 |
+
|
191 |
+
// See if its local or remote
|
192 |
+
if ( strstr( $file_path, 'http:' ) || strstr( $file_path, 'https:' ) || strstr( $file_path, 'ftp:' ) ) {
|
193 |
+
$remote_file = true;
|
194 |
+
} else {
|
195 |
+
$remote_file = false;
|
196 |
+
$file_path = realpath( current( explode( '?', $file_path ) ) );
|
197 |
+
}
|
198 |
+
|
199 |
+
// Get Mime Type
|
200 |
+
$mime_type = "application/force-download";
|
201 |
+
|
202 |
+
foreach ( get_allowed_mime_types() as $mime => $type ) {
|
203 |
+
$mimes = explode( '|', $mime );
|
204 |
+
if ( in_array( $version->filetype, $mimes ) ) {
|
205 |
+
$mime_type = $type;
|
206 |
+
break;
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
// HEADERS
|
211 |
+
if ( ! ini_get('safe_mode') )
|
212 |
+
@set_time_limit(0);
|
213 |
+
|
214 |
+
if ( function_exists( 'get_magic_quotes_runtime' ) && get_magic_quotes_runtime() )
|
215 |
+
@set_magic_quotes_runtime(0);
|
216 |
+
|
217 |
+
if( function_exists( 'apache_setenv' ) )
|
218 |
+
@apache_setenv( 'no-gzip', 1 );
|
219 |
+
|
220 |
+
@session_write_close();
|
221 |
+
@ini_set( 'zlib.output_compression', 'Off' );
|
222 |
+
@ob_end_clean();
|
223 |
+
|
224 |
+
if ( ob_get_level() )
|
225 |
+
@ob_end_clean(); // Zip corruption fix
|
226 |
+
|
227 |
+
nocache_headers();
|
228 |
+
|
229 |
+
$file_name = basename( $file_path );
|
230 |
+
|
231 |
+
if ( strstr( $file_name, '?' ) )
|
232 |
+
$file_name = current( explode( '?', $file_name ) );
|
233 |
+
|
234 |
+
header( "Robots: none" );
|
235 |
+
header( "Content-Type: " . $mime_type );
|
236 |
+
header( "Content-Description: File Transfer" );
|
237 |
+
header( "Content-Disposition: attachment; filename=\"" . $file_name . "\";" );
|
238 |
+
header( "Content-Transfer-Encoding: binary" );
|
239 |
+
|
240 |
+
if ( $version->filesize )
|
241 |
+
header( "Content-Length: " . $version->filesize );
|
242 |
+
|
243 |
+
if ( get_option( 'dlm_xsendfile_enabled' ) ) {
|
244 |
+
|
245 |
+
if ( getcwd() )
|
246 |
+
$file_path = trim( preg_replace( '`^' . getcwd() . '`' , '', $file_path ), '/' );
|
247 |
+
|
248 |
+
header( "Content-Disposition: attachment; filename=\"" . $file_name . "\";" );
|
249 |
+
|
250 |
+
if ( function_exists( 'apache_get_modules' ) && in_array( 'mod_xsendfile', apache_get_modules() ) ) {
|
251 |
+
if ( function_exists( 'dlm_create_log' ) )
|
252 |
+
dlm_create_log( 'download', 'redirected', __( 'Redirected to file', 'download_monitor' ), $download, $version );
|
253 |
+
|
254 |
+
header("X-Sendfile: $file_path");
|
255 |
+
exit;
|
256 |
+
} elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'lighttpd' ) ) {
|
257 |
+
if ( function_exists( 'dlm_create_log' ) )
|
258 |
+
dlm_create_log( 'download', 'redirected', __( 'Redirected to file', 'download_monitor' ), $download, $version );
|
259 |
+
|
260 |
+
header( "X-Lighttpd-Sendfile: $file_path" );
|
261 |
+
exit;
|
262 |
+
} elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'nginx' ) || stristr( getenv( 'SERVER_SOFTWARE' ), 'cherokee' ) ) {
|
263 |
+
if ( function_exists( 'dlm_create_log' ) )
|
264 |
+
dlm_create_log( 'download', 'redirected', __( 'Redirected to file', 'download_monitor' ), $download, $version );
|
265 |
+
|
266 |
+
header( "X-Accel-Redirect: /$file_path" );
|
267 |
+
exit;
|
268 |
+
}
|
269 |
+
}
|
270 |
+
|
271 |
+
if ( $this->readfile_chunked( $file_path ) ) {
|
272 |
+
// Complete!
|
273 |
+
if ( function_exists( 'dlm_create_log' ) )
|
274 |
+
dlm_create_log( 'download', 'completed', '', $download, $version );
|
275 |
+
|
276 |
+
} elseif ( $remote_file ) {
|
277 |
+
// Redirect - we can't track if this completes or not
|
278 |
+
if ( function_exists( 'dlm_create_log' ) )
|
279 |
+
dlm_create_log( 'download', 'redirected', __( 'Redirected to remote file.', 'download_monitor' ), $download, $version );
|
280 |
+
|
281 |
+
header( 'Location: ' . $file_path );
|
282 |
+
} else {
|
283 |
+
if ( function_exists( 'dlm_create_log' ) )
|
284 |
+
dlm_create_log( 'download', 'failed', __( 'File not found', 'download_monitor' ), $download, $version );
|
285 |
+
|
286 |
+
wp_die( __( 'File not found.', 'download_monitor' ) . ' <a href="' . home_url() . '">' . __( 'Go to homepage →', 'download_monitor' ) . '</a>', __( 'Download Error', 'download_monitor' ) );
|
287 |
+
}
|
288 |
+
|
289 |
+
exit;
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* readfile_chunked
|
294 |
+
*
|
295 |
+
* Reads file in chunks so big downloads are possible without changing PHP.INI - http://codeigniter.com/wiki/Download_helper_for_large_files/
|
296 |
+
*
|
297 |
+
* @access public
|
298 |
+
* @param string file
|
299 |
+
* @param boolean return bytes of file
|
300 |
+
* @return void
|
301 |
+
*/
|
302 |
+
public function readfile_chunked( $file, $retbytes = true ) {
|
303 |
+
|
304 |
+
$chunksize = 1 * ( 1024 * 1024 );
|
305 |
+
$buffer = '';
|
306 |
+
$cnt = 0;
|
307 |
+
|
308 |
+
$handle = @fopen( $file, 'r' );
|
309 |
+
if ( $handle === false )
|
310 |
+
return false;
|
311 |
+
|
312 |
+
while ( ! feof( $handle ) ) {
|
313 |
+
$buffer = fread( $handle, $chunksize );
|
314 |
+
echo $buffer;
|
315 |
+
ob_flush();
|
316 |
+
flush();
|
317 |
+
|
318 |
+
if ( $retbytes )
|
319 |
+
$cnt += strlen( $buffer );
|
320 |
+
}
|
321 |
+
|
322 |
+
$status = fclose( $handle );
|
323 |
+
|
324 |
+
if ( $retbytes && $status )
|
325 |
+
return $cnt;
|
326 |
+
|
327 |
+
return $status;
|
328 |
+
}
|
329 |
+
}
|
330 |
+
|
331 |
+
$GLOBALS['DLM_Download_Handler'] = new DLM_Download_Handler();
|
includes/class-dlm-download-version.php
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* DLM_Download_Version class.
|
5 |
+
*/
|
6 |
+
class DLM_Download_Version {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* __construct function.
|
10 |
+
*
|
11 |
+
* @access public
|
12 |
+
* @return void
|
13 |
+
*/
|
14 |
+
public function __construct( $version_id, $download_id ) {
|
15 |
+
$this->id = absint( $version_id );
|
16 |
+
$this->download_id = absint( $download_id );
|
17 |
+
|
18 |
+
// Get Version Data
|
19 |
+
$this->mirrors = array_filter( (array) get_post_meta( $this->id, '_files', true ) );
|
20 |
+
$this->url = current( $this->mirrors );
|
21 |
+
$this->filename = current( explode( '?', basename( $this->url ) ) );
|
22 |
+
$this->filetype = strtolower( substr( strrchr( $this->filename, "." ), 1 ) );
|
23 |
+
$this->version = get_post_meta( $this->id, '_version', true );
|
24 |
+
$this->download_count = get_post_meta( $this->id, '_download_count', true );
|
25 |
+
$this->filesize = get_post_meta( $this->id, '_filesize', true );
|
26 |
+
|
27 |
+
// If data is not set, load it
|
28 |
+
if ( ! $this->filesize )
|
29 |
+
$this->filesize = $this->get_filesize( $this->url );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* increase_download_count function.
|
34 |
+
*
|
35 |
+
* @access public
|
36 |
+
* @return void
|
37 |
+
*/
|
38 |
+
public function increase_download_count() {
|
39 |
+
// File download_count
|
40 |
+
$this->download_count = absint( get_post_meta( $this->id, '_download_count', true ) ) + 1;
|
41 |
+
update_post_meta( $this->id, '_download_count', $this->download_count );
|
42 |
+
|
43 |
+
// Parent download download_count
|
44 |
+
$parent_download_count = absint( get_post_meta( $this->download_id, '_download_count', true ) ) + 1;
|
45 |
+
update_post_meta( $this->download_id, '_download_count', $parent_download_count );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* get_filesize function.
|
50 |
+
*
|
51 |
+
* @access public
|
52 |
+
* @param mixed $file
|
53 |
+
* @return void
|
54 |
+
*/
|
55 |
+
public function get_filesize( $file_path ) {
|
56 |
+
|
57 |
+
$filesize = null;
|
58 |
+
|
59 |
+
if ( ! is_multisite() ) {
|
60 |
+
|
61 |
+
$file_path = str_replace( site_url( '/', 'https' ), ABSPATH, $file_path );
|
62 |
+
$file_path = str_replace( site_url( '/', 'http' ), ABSPATH, $file_path );
|
63 |
+
|
64 |
+
} else {
|
65 |
+
|
66 |
+
// Try to replace network url
|
67 |
+
$file_path = str_replace( network_admin_url( '/', 'https' ), ABSPATH, $file_path );
|
68 |
+
$file_path = str_replace( network_admin_url( '/', 'http' ), ABSPATH, $file_path );
|
69 |
+
|
70 |
+
// Try to replace upload URL
|
71 |
+
$upload_dir = wp_upload_dir();
|
72 |
+
$file_path = str_replace( $upload_dir['baseurl'], $upload_dir['basedir'], $file_path );
|
73 |
+
}
|
74 |
+
|
75 |
+
if ( file_exists( $file_path ) && ( $filesize = filesize( $file_path ) ) )
|
76 |
+
$filesize = $filesize;
|
77 |
+
else {
|
78 |
+
$file = wp_remote_head( $file_path );
|
79 |
+
|
80 |
+
if ( ! is_wp_error( $file ) && ! empty( $file['headers']['content-length'] ) )
|
81 |
+
$filesize = $file['headers']['content-length'];
|
82 |
+
}
|
83 |
+
|
84 |
+
update_post_meta( $this->id, '_filesize', $filesize );
|
85 |
+
|
86 |
+
return $filesize;
|
87 |
+
}
|
88 |
+
}
|
includes/class-dlm-download.php
ADDED
@@ -0,0 +1,458 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* DLM_Download class.
|
4 |
+
*/
|
5 |
+
class DLM_Download {
|
6 |
+
|
7 |
+
private $files;
|
8 |
+
private $file_version_ids;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* __construct function.
|
12 |
+
*
|
13 |
+
* @access public
|
14 |
+
* @param mixed $id
|
15 |
+
* @return void
|
16 |
+
*/
|
17 |
+
public function __construct( $id ) {
|
18 |
+
$this->id = absint( $id );
|
19 |
+
$this->post = get_post( $this->id );
|
20 |
+
$this->version_id = ''; // Use latest current version
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* __isset function.
|
25 |
+
*
|
26 |
+
* @access public
|
27 |
+
* @param mixed $key
|
28 |
+
* @return bool
|
29 |
+
*/
|
30 |
+
public function __isset( $key ) {
|
31 |
+
return metadata_exists( 'post', $this->id, '_' . $key );
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* __get function.
|
36 |
+
*
|
37 |
+
* @access public
|
38 |
+
* @param mixed $key
|
39 |
+
* @return mixed
|
40 |
+
*/
|
41 |
+
public function __get( $key ) {
|
42 |
+
|
43 |
+
// Get values or default if not set
|
44 |
+
if ( 'members_only' == $key )
|
45 |
+
$value = ( $value = get_post_meta( $this->id, '_members_only', true ) ) ? $value : 'no';
|
46 |
+
|
47 |
+
elseif ( 'featured' == $key )
|
48 |
+
$value = ( $value = get_post_meta( $this->id, '_featured', true ) ) ? $value : 'no';
|
49 |
+
|
50 |
+
else
|
51 |
+
$value = get_post_meta( $this->id, '_' . $key, true );
|
52 |
+
|
53 |
+
return $value;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* exists function.
|
58 |
+
*
|
59 |
+
* @access public
|
60 |
+
* @return void
|
61 |
+
*/
|
62 |
+
public function exists() {
|
63 |
+
return ( ! is_null( $this->post ) );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* version_exists function.
|
68 |
+
*
|
69 |
+
* @access public
|
70 |
+
* @param mixed $version_id
|
71 |
+
* @return void
|
72 |
+
*/
|
73 |
+
public function version_exists( $version_id ) {
|
74 |
+
return in_array( $version_id, array_keys( $this->get_file_versions() ) );
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Set the download to a version other than the current / latest version it defaults to.
|
79 |
+
*
|
80 |
+
* @access public
|
81 |
+
* @param mixed $version_id
|
82 |
+
* @return void
|
83 |
+
*/
|
84 |
+
public function set_version( $version_id = '' ) {
|
85 |
+
if ( $this->version_exists( $version_id ) )
|
86 |
+
$this->version_id = $version_id;
|
87 |
+
else
|
88 |
+
$this->version_id = '';
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* get_title function.
|
93 |
+
*
|
94 |
+
* @access public
|
95 |
+
* @return void
|
96 |
+
*/
|
97 |
+
public function get_the_title() {
|
98 |
+
return $this->post->post_title;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* the_title function.
|
103 |
+
*
|
104 |
+
* @access public
|
105 |
+
* @return void
|
106 |
+
*/
|
107 |
+
public function the_title() {
|
108 |
+
echo $this->get_the_title();
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* get_the_short_description function.
|
113 |
+
*
|
114 |
+
* @access public
|
115 |
+
* @return void
|
116 |
+
*/
|
117 |
+
public function get_the_short_description() {
|
118 |
+
return wpautop( $this->post->post_excerpt );
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* the_short_description function.
|
123 |
+
*
|
124 |
+
* @access public
|
125 |
+
* @return void
|
126 |
+
*/
|
127 |
+
public function the_short_description() {
|
128 |
+
echo $this->get_the_short_description();
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* get_the_image function.
|
133 |
+
*
|
134 |
+
* @access public
|
135 |
+
* @param string $size (default: 'full')
|
136 |
+
* @return void
|
137 |
+
*/
|
138 |
+
public function get_the_image( $size = 'full' ) {
|
139 |
+
global $download_monitor;
|
140 |
+
|
141 |
+
if ( has_post_thumbnail( $this->id ) )
|
142 |
+
return get_the_post_thumbnail( $this->id, $size );
|
143 |
+
else
|
144 |
+
return '<img alt="Placeholder" class="wp-post-image" src="' . apply_filters( 'dlm_placeholder_image_src', $download_monitor->plugin_url() . '/assets/images/placeholder.png' ) . '" />';
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* the_image function.
|
149 |
+
*
|
150 |
+
* @access public
|
151 |
+
* @param string $size (default: 'full')
|
152 |
+
* @return void
|
153 |
+
*/
|
154 |
+
public function the_image( $size = 'full' ) {
|
155 |
+
echo $this->get_the_image( $size );
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* get_author function.
|
160 |
+
*
|
161 |
+
* @access public
|
162 |
+
* @return void
|
163 |
+
*/
|
164 |
+
public function get_the_author() {
|
165 |
+
$author_id = $this->post->post_author;
|
166 |
+
$user = get_user_by( 'ID', $author_id );
|
167 |
+
if ( $user )
|
168 |
+
return $user->display_name;
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* the_author function.
|
173 |
+
*
|
174 |
+
* @access public
|
175 |
+
* @return void
|
176 |
+
*/
|
177 |
+
public function the_author() {
|
178 |
+
echo $this->get_the_author();
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* the_download_link function.
|
183 |
+
*
|
184 |
+
* @access public
|
185 |
+
* @return void
|
186 |
+
*/
|
187 |
+
public function the_download_link() {
|
188 |
+
echo $this->get_the_download_link();
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* get_the_download_link function.
|
193 |
+
*
|
194 |
+
* @access public
|
195 |
+
* @return void
|
196 |
+
*/
|
197 |
+
public function get_the_download_link() {
|
198 |
+
$scheme = parse_url( get_option( 'home' ), PHP_URL_SCHEME );
|
199 |
+
$endpoint = ( $endpoint = get_option( 'dlm_download_endpoint' ) ) ? $endpoint : 'download';
|
200 |
+
$ep_value = get_option( 'dlm_download_endpoint_value' );
|
201 |
+
|
202 |
+
switch ( $ep_value ) {
|
203 |
+
case 'slug' :
|
204 |
+
$value = $this->post->post_name;
|
205 |
+
break;
|
206 |
+
default :
|
207 |
+
$value = $this->id;
|
208 |
+
break;
|
209 |
+
}
|
210 |
+
|
211 |
+
if ( get_option('permalink_structure') ) {
|
212 |
+
$link = home_url( '/' . $endpoint . '/' . $value . '/', $scheme );
|
213 |
+
} else {
|
214 |
+
$link = add_query_arg( $endpoint, $value, home_url( '', $scheme ) );
|
215 |
+
}
|
216 |
+
|
217 |
+
if ( $this->version_id ) {
|
218 |
+
|
219 |
+
if ( $this->has_version_number() )
|
220 |
+
$link = add_query_arg( 'version', $this->get_the_version_number(), $link );
|
221 |
+
else
|
222 |
+
$link = add_query_arg( 'v', $this->version_id, $link );
|
223 |
+
}
|
224 |
+
|
225 |
+
return apply_filters( 'dlm_download_get_the_download_link', esc_url_raw( $link ), $this, $this->version_id );
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* the_download_count function.
|
230 |
+
*
|
231 |
+
* @access public
|
232 |
+
* @return void
|
233 |
+
*/
|
234 |
+
public function the_download_count() {
|
235 |
+
echo $this->get_the_download_count();
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* get_the_download_count function.
|
240 |
+
*
|
241 |
+
* @access public
|
242 |
+
* @return void
|
243 |
+
*/
|
244 |
+
public function get_the_download_count() {
|
245 |
+
if ( $this->version_id ) {
|
246 |
+
return absint( $this->get_file_version()->download_count );
|
247 |
+
} else {
|
248 |
+
return absint( $this->download_count );
|
249 |
+
}
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* has_version_number function.
|
254 |
+
*
|
255 |
+
* @access public
|
256 |
+
* @return void
|
257 |
+
*/
|
258 |
+
public function has_version_number() {
|
259 |
+
return ! empty( $this->get_file_version()->version );
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* get_the_version_number function.
|
264 |
+
*
|
265 |
+
* @access public
|
266 |
+
* @return void
|
267 |
+
*/
|
268 |
+
public function get_the_version_number() {
|
269 |
+
return ( $version = $this->get_file_version()->version ) ? $version : '1';
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* the_version_number function.
|
274 |
+
*
|
275 |
+
* @access public
|
276 |
+
* @return void
|
277 |
+
*/
|
278 |
+
public function the_version_number() {
|
279 |
+
echo $this->get_the_version_number();
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* get_the_filename function.
|
284 |
+
*
|
285 |
+
* @access public
|
286 |
+
* @return void
|
287 |
+
*/
|
288 |
+
public function get_the_filename() {
|
289 |
+
return $this->get_file_version()->filename;
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* the_filename function.
|
294 |
+
*
|
295 |
+
* @access public
|
296 |
+
* @return void
|
297 |
+
*/
|
298 |
+
public function the_filename() {
|
299 |
+
echo $this->get_the_filename();
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* get_the_filesize function.
|
304 |
+
*
|
305 |
+
* @access public
|
306 |
+
* @return void
|
307 |
+
*/
|
308 |
+
public function get_the_filesize() {
|
309 |
+
$filesize = $this->get_file_version()->filesize;
|
310 |
+
|
311 |
+
if ( $filesize )
|
312 |
+
return size_format( $filesize );
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* the_filesize function.
|
317 |
+
*
|
318 |
+
* @access public
|
319 |
+
* @return void
|
320 |
+
*/
|
321 |
+
public function the_filesize() {
|
322 |
+
echo $this->get_the_filesize();
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* get_the_filetype function.
|
327 |
+
*
|
328 |
+
* @access public
|
329 |
+
* @return void
|
330 |
+
*/
|
331 |
+
public function get_the_filetype() {
|
332 |
+
return $this->get_file_version()->filetype;
|
333 |
+
}
|
334 |
+
|
335 |
+
/**
|
336 |
+
* the_filetype function.
|
337 |
+
*
|
338 |
+
* @access public
|
339 |
+
* @return void
|
340 |
+
*/
|
341 |
+
public function the_filetype() {
|
342 |
+
echo $this->get_the_filetype();
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Get a version by ID, or default to current version.
|
347 |
+
*
|
348 |
+
* @access public
|
349 |
+
* @return void
|
350 |
+
*/
|
351 |
+
public function get_file_version() {
|
352 |
+
$version = false;
|
353 |
+
|
354 |
+
if ( $this->version_id ) {
|
355 |
+
$versions = $this->get_file_versions();
|
356 |
+
|
357 |
+
if ( ! empty( $versions[ $this->version_id ] ) )
|
358 |
+
$version = $versions[ $this->version_id ];
|
359 |
+
|
360 |
+
} elseif ( $versions = $this->get_file_versions() ) {
|
361 |
+
$version = array_shift( $versions );
|
362 |
+
}
|
363 |
+
|
364 |
+
if ( ! $version ) {
|
365 |
+
|
366 |
+
$version = new stdClass();
|
367 |
+
|
368 |
+
$version->id = 0;
|
369 |
+
$version->download_id = $this->id;
|
370 |
+
$version->mirrors = array();
|
371 |
+
$version->url = '';
|
372 |
+
$version->filename = '';
|
373 |
+
$version->filetype = '';
|
374 |
+
$version->version = '';
|
375 |
+
$version->download_count = '';
|
376 |
+
$version->filesize = '';
|
377 |
+
}
|
378 |
+
|
379 |
+
return $version;
|
380 |
+
}
|
381 |
+
|
382 |
+
/**
|
383 |
+
* Get a version ID from a version string.
|
384 |
+
*
|
385 |
+
* @access public
|
386 |
+
* @return void
|
387 |
+
*/
|
388 |
+
public function get_version_id( $version_string = '' ) {
|
389 |
+
$versions = $this->get_file_versions();
|
390 |
+
|
391 |
+
foreach ( $versions as $version_id => $version )
|
392 |
+
if ( version_compare( $version->version, $version_string, '=' ) )
|
393 |
+
return $version_id;
|
394 |
+
}
|
395 |
+
|
396 |
+
/**
|
397 |
+
* is_featured function.
|
398 |
+
*
|
399 |
+
* @access public
|
400 |
+
* @return bool
|
401 |
+
*/
|
402 |
+
function is_featured() {
|
403 |
+
return ( $this->featured == 'yes' ) ? true : false;
|
404 |
+
}
|
405 |
+
|
406 |
+
/**
|
407 |
+
* is_members_only function.
|
408 |
+
*
|
409 |
+
* @access public
|
410 |
+
* @return bool
|
411 |
+
*/
|
412 |
+
function is_members_only() {
|
413 |
+
return ( $this->members_only == 'yes' ) ? true : false;
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* get_file_version_ids function.
|
418 |
+
*
|
419 |
+
* @access public
|
420 |
+
* @return void
|
421 |
+
*/
|
422 |
+
function get_file_version_ids() {
|
423 |
+
if ( ! is_array( $this->file_version_ids ) ) {
|
424 |
+
|
425 |
+
$this->file_version_ids = array();
|
426 |
+
|
427 |
+
$transient_name = 'dlm_children_ids_' . $this->id;
|
428 |
+
|
429 |
+
if ( false === ( $this->file_version_ids = get_transient( $transient_name ) ) ) {
|
430 |
+
|
431 |
+
$this->file_version_ids = get_posts( 'post_parent=' . $this->id . '&post_type=dlm_download_version&orderby=menu_order&order=ASC&fields=ids&post_status=publish&numberposts=-1' );
|
432 |
+
|
433 |
+
set_transient( $transient_name, $this->file_version_ids );
|
434 |
+
}
|
435 |
+
}
|
436 |
+
|
437 |
+
return $this->file_version_ids;
|
438 |
+
}
|
439 |
+
|
440 |
+
/**
|
441 |
+
* get_file_versions function.
|
442 |
+
*
|
443 |
+
* @access public
|
444 |
+
* @return void
|
445 |
+
*/
|
446 |
+
public function get_file_versions() {
|
447 |
+
if ( $this->files )
|
448 |
+
return $this->files;
|
449 |
+
|
450 |
+
$version_ids = $this->get_file_version_ids();
|
451 |
+
$this->files = array();
|
452 |
+
|
453 |
+
foreach ( $version_ids as $version_id )
|
454 |
+
$this->files[ $version_id ] = new DLM_Download_Version( $version_id, $this->id );
|
455 |
+
|
456 |
+
return $this->files;
|
457 |
+
}
|
458 |
+
}
|
includes/class-dlm-logging.php
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* DLM_Logging class.
|
7 |
+
*/
|
8 |
+
class DLM_Logging {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* create_log function.
|
12 |
+
*
|
13 |
+
* @access public
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
public function create_log( $type, $status, $message, $download, $version ) {
|
17 |
+
global $wpdb;
|
18 |
+
|
19 |
+
$wpdb->insert(
|
20 |
+
$wpdb->download_log,
|
21 |
+
array(
|
22 |
+
'type' => $type,
|
23 |
+
'user_id' => absint( get_current_user_id() ),
|
24 |
+
'user_ip' => $this->get_user_ip(),
|
25 |
+
'user_agent' => $this->get_user_ua(),
|
26 |
+
'download_id' => absint( $download->id ),
|
27 |
+
'version_id' => absint( $version->id ),
|
28 |
+
'version' => $version->version,
|
29 |
+
'download_date' => current_time( 'mysql' ),
|
30 |
+
'download_status' => $status,
|
31 |
+
'download_status_message' => $message
|
32 |
+
),
|
33 |
+
array(
|
34 |
+
'%s',
|
35 |
+
'%d',
|
36 |
+
'%s',
|
37 |
+
'%s',
|
38 |
+
'%d',
|
39 |
+
'%s',
|
40 |
+
'%s',
|
41 |
+
'%s',
|
42 |
+
'%s'
|
43 |
+
)
|
44 |
+
);
|
45 |
+
|
46 |
+
return $wpdb->insert_id;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* get_user_ip function.
|
51 |
+
*
|
52 |
+
* @access private
|
53 |
+
* @return void
|
54 |
+
*/
|
55 |
+
private function get_user_ip() {
|
56 |
+
return sanitize_text_field( ! empty( $_SERVER['HTTP_X_FORWARD_FOR'] ) ? $_SERVER['HTTP_X_FORWARD_FOR'] : $_SERVER['REMOTE_ADDR'] );
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* get_user_ua function.
|
61 |
+
*
|
62 |
+
* @access private
|
63 |
+
* @return void
|
64 |
+
*/
|
65 |
+
private function get_user_ua() {
|
66 |
+
return sanitize_text_field( isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '' );
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
$GLOBALS['dlm_logging'] = new DLM_Logging();
|
71 |
+
|
72 |
+
/**
|
73 |
+
* dlm_create_log function.
|
74 |
+
*
|
75 |
+
* @access public
|
76 |
+
* @param string $type (default: '')
|
77 |
+
* @param string $status (default: '')
|
78 |
+
* @param string $message (default: '')
|
79 |
+
* @param mixed $download
|
80 |
+
* @param mixed $version
|
81 |
+
* @return void
|
82 |
+
*/
|
83 |
+
function dlm_create_log( $type = '', $status = '', $message = '', $download, $version ) {
|
84 |
+
global $dlm_logging;
|
85 |
+
|
86 |
+
$dlm_logging->create_log( $type, $status, $message, $download, $version );
|
87 |
+
}
|
includes/class-dlm-shortcodes.php
ADDED
@@ -0,0 +1,324 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* DLM_Shortcodes class.
|
7 |
+
*/
|
8 |
+
class DLM_Shortcodes {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* __construct function.
|
12 |
+
*
|
13 |
+
* @access public
|
14 |
+
* @return void
|
15 |
+
*/
|
16 |
+
public function __construct() {
|
17 |
+
add_shortcode( 'total_downloads', array( $this, 'total_downloads' ) );
|
18 |
+
add_shortcode( 'total_files', array( $this, 'total_files' ) );
|
19 |
+
add_shortcode( 'download', array( $this, 'download' ) );
|
20 |
+
add_shortcode( 'download_data', array( $this, 'download_data' ) );
|
21 |
+
add_shortcode( 'downloads', array( $this, 'downloads' ) );
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* total_downloads function.
|
26 |
+
*
|
27 |
+
* @access public
|
28 |
+
* @return void
|
29 |
+
*/
|
30 |
+
public function total_downloads() {
|
31 |
+
global $wpdb;
|
32 |
+
|
33 |
+
return $wpdb->get_var( "
|
34 |
+
SELECT SUM( meta_value ) FROM $wpdb->postmeta
|
35 |
+
LEFT JOIN $wpdb->posts on $wpdb->postmeta.post_id = $wpdb->posts.ID
|
36 |
+
WHERE meta_key = '_download_count'
|
37 |
+
AND post_type = 'dlm_download'
|
38 |
+
AND post_status = 'publish'
|
39 |
+
" );
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* total_files function.
|
44 |
+
*
|
45 |
+
* @access public
|
46 |
+
* @return void
|
47 |
+
*/
|
48 |
+
public function total_files() {
|
49 |
+
$count_posts = wp_count_posts( 'dlm_download' );
|
50 |
+
|
51 |
+
return $count_posts->publish;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* download function.
|
56 |
+
*
|
57 |
+
* @access public
|
58 |
+
* @param mixed $atts
|
59 |
+
* @return void
|
60 |
+
*/
|
61 |
+
public function download( $atts ) {
|
62 |
+
global $download_monitor, $dlm_download;
|
63 |
+
|
64 |
+
extract( shortcode_atts( array(
|
65 |
+
'id' => '',
|
66 |
+
'autop' => false,
|
67 |
+
'template' => get_option( 'dlm_default_template' ),
|
68 |
+
'version_id' => '',
|
69 |
+
'version' => ''
|
70 |
+
), $atts ) );
|
71 |
+
|
72 |
+
$id = apply_filters( 'dlm_shortcode_download_id', $id );
|
73 |
+
|
74 |
+
if ( empty( $id ) )
|
75 |
+
return;
|
76 |
+
|
77 |
+
ob_start();
|
78 |
+
|
79 |
+
$downloads = new WP_Query( array(
|
80 |
+
'post_type' => 'dlm_download',
|
81 |
+
'posts_per_page' => 1,
|
82 |
+
'no_found_rows' => 1,
|
83 |
+
'post_status' => 'publish',
|
84 |
+
'p' => $id
|
85 |
+
) );
|
86 |
+
|
87 |
+
if ( $downloads->have_posts() ) {
|
88 |
+
|
89 |
+
while ( $downloads->have_posts() ) {
|
90 |
+
$downloads->the_post();
|
91 |
+
|
92 |
+
if ( $version )
|
93 |
+
$version_id = $dlm_download->get_version_id( $version );
|
94 |
+
|
95 |
+
if ( $version_id )
|
96 |
+
$dlm_download->set_version( $version_id );
|
97 |
+
|
98 |
+
$download_monitor->get_template_part( 'content-download', $template );
|
99 |
+
}
|
100 |
+
|
101 |
+
} else {
|
102 |
+
echo '[' . __( 'Download not found', 'download_monitor' ) . ']';
|
103 |
+
}
|
104 |
+
|
105 |
+
wp_reset_postdata();
|
106 |
+
|
107 |
+
if ( $autop === 'true' || $autop === true )
|
108 |
+
return wpautop( ob_get_clean() );
|
109 |
+
else
|
110 |
+
return ob_get_clean();
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* download_data function.
|
115 |
+
*
|
116 |
+
* @access public
|
117 |
+
* @param mixed $atts
|
118 |
+
* @param mixed $content
|
119 |
+
* @return void
|
120 |
+
*/
|
121 |
+
public function download_data( $atts ) {
|
122 |
+
global $download_monitor;
|
123 |
+
|
124 |
+
extract( shortcode_atts( array(
|
125 |
+
'id' => '',
|
126 |
+
'data' => '',
|
127 |
+
'version_id' => '',
|
128 |
+
'version' => ''
|
129 |
+
), $atts ) );
|
130 |
+
|
131 |
+
$id = apply_filters( 'dlm_shortcode_download_id', $id );
|
132 |
+
|
133 |
+
if ( empty( $id ) || empty( $data ) )
|
134 |
+
return;
|
135 |
+
|
136 |
+
$download = new DLM_Download( $id );
|
137 |
+
|
138 |
+
if ( $version )
|
139 |
+
$version_id = $download->get_version_id( $version );
|
140 |
+
|
141 |
+
if ( $version_id )
|
142 |
+
$download->set_version( $version_id );
|
143 |
+
|
144 |
+
switch ( $data ) {
|
145 |
+
|
146 |
+
// File / Version Info
|
147 |
+
case 'filename' :
|
148 |
+
return $download->get_the_filename();
|
149 |
+
case 'filetype' :
|
150 |
+
return $download->get_the_filetype();
|
151 |
+
case 'filesize' :
|
152 |
+
return $download->get_the_filesize();
|
153 |
+
case 'version' :
|
154 |
+
return $download->get_the_version_number();
|
155 |
+
|
156 |
+
// Download Info
|
157 |
+
case 'title' :
|
158 |
+
return $download->get_the_title();
|
159 |
+
case 'short_description' :
|
160 |
+
return $download->get_the_short_description();
|
161 |
+
case 'download_link' :
|
162 |
+
return $download->get_the_download_link();
|
163 |
+
case 'download_count' :
|
164 |
+
return $download->get_the_download_count();
|
165 |
+
case 'post_content' :
|
166 |
+
return wpautop( wptexturize( do_shortcode( $download->post->post_content ) ) );
|
167 |
+
case 'post_date' :
|
168 |
+
return date_i18n( get_option( 'date_format', $download->post->post_date ) );
|
169 |
+
case 'author' :
|
170 |
+
return $download->get_the_author();
|
171 |
+
|
172 |
+
// Images
|
173 |
+
case 'image' :
|
174 |
+
return $download->get_the_image( 'full' );
|
175 |
+
case 'thumbnail' :
|
176 |
+
return $download->get_the_image( 'thumbnail' );
|
177 |
+
|
178 |
+
// Taxonomies
|
179 |
+
case 'tags' :
|
180 |
+
return get_the_term_list( $id, 'dlm_download_tags', '', ', ', '' );
|
181 |
+
case 'categories' :
|
182 |
+
return get_the_term_list( $id, 'dlm_download_categories', '', ', ', '' );
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* downloads function.
|
188 |
+
*
|
189 |
+
* @access public
|
190 |
+
* @param mixed $atts
|
191 |
+
* @return void
|
192 |
+
*/
|
193 |
+
public function downloads( $atts ) {
|
194 |
+
global $download_monitor;
|
195 |
+
|
196 |
+
extract( shortcode_atts( array(
|
197 |
+
// Query args
|
198 |
+
'per_page' => '-1', // -1 = no limit
|
199 |
+
'orderby' => 'title', // title, rand, ID, none, date, modifed, post__in, download_count
|
200 |
+
'order' => 'desc', // ASC or DESC
|
201 |
+
'include' => '', // Comma separate IDS
|
202 |
+
'exclude' => '', // Comma separate IDS
|
203 |
+
'offset' => '',
|
204 |
+
'category' => '', // Comma separate slugs
|
205 |
+
'tag' => '', // Comma separate slugs
|
206 |
+
'featured' => false, // Set to true to only pull featured downloads
|
207 |
+
'members_only' => false, // Set to true to only pull member downloads
|
208 |
+
|
209 |
+
// Output args
|
210 |
+
'template' => get_option( 'dlm_default_template' ),
|
211 |
+
'loop_start' => '<ul class="dlm-downloads">',
|
212 |
+
'loop_end' => '</ul>',
|
213 |
+
'before' => '<li>',
|
214 |
+
'after' => '</li>'
|
215 |
+
), $atts ) );
|
216 |
+
|
217 |
+
$post__in = ! empty( $include ) ? explode( ',', $include ) : '';
|
218 |
+
$post__not_in = ! empty( $exclude ) ? explode( ',', $exclude ) : '';
|
219 |
+
$order = strtoupper( $order );
|
220 |
+
$meta_key = '';
|
221 |
+
|
222 |
+
switch ( $orderby ) {
|
223 |
+
case 'title' :
|
224 |
+
case 'rand' :
|
225 |
+
case 'ID' :
|
226 |
+
case 'date' :
|
227 |
+
case 'modified' :
|
228 |
+
case 'post__in' :
|
229 |
+
$orderby = $orderby;
|
230 |
+
break;
|
231 |
+
case 'id' :
|
232 |
+
$orderby = 'ID';
|
233 |
+
break;
|
234 |
+
case 'hits' :
|
235 |
+
case 'count' :
|
236 |
+
case 'download_count' :
|
237 |
+
$orderby = 'meta_value';
|
238 |
+
$meta_key = '_download_count';
|
239 |
+
break;
|
240 |
+
default :
|
241 |
+
$orderby = 'title';
|
242 |
+
break;
|
243 |
+
}
|
244 |
+
|
245 |
+
$args = array(
|
246 |
+
'post_type' => 'dlm_download',
|
247 |
+
'posts_per_page' => $per_page,
|
248 |
+
'offset' => $offset,
|
249 |
+
'no_found_rows' => 1,
|
250 |
+
'post_status' => 'publish',
|
251 |
+
'orderby' => $orderby,
|
252 |
+
'order' => $order,
|
253 |
+
'$meta_key' => $meta_key,
|
254 |
+
'post__in' => $post__in,
|
255 |
+
'post__not_in' => $post__not_in,
|
256 |
+
'meta_query' => array()
|
257 |
+
);
|
258 |
+
|
259 |
+
if ( $category || $tag ) {
|
260 |
+
$args['tax_query'] = array( 'relation' => 'AND' );
|
261 |
+
|
262 |
+
$categories = array_filter( explode( ',', $category ) );
|
263 |
+
$tags = array_filter( explode( ',', $tag ) );
|
264 |
+
|
265 |
+
if ( ! empty( $categories ) ) {
|
266 |
+
$args['tax_query'][] = array(
|
267 |
+
'taxonomy' => 'dlm_download_category',
|
268 |
+
'field' => 'slug',
|
269 |
+
'terms' => $categories
|
270 |
+
);
|
271 |
+
}
|
272 |
+
|
273 |
+
if ( ! empty( $tags ) ) {
|
274 |
+
$args['tax_query'][] = array(
|
275 |
+
'taxonomy' => 'dlm_download_tag',
|
276 |
+
'field' => 'slug',
|
277 |
+
'terms' => $tags
|
278 |
+
);
|
279 |
+
}
|
280 |
+
}
|
281 |
+
|
282 |
+
if ( $featured === 'true' || $featured === true ) {
|
283 |
+
$args['meta_query'][] = array(
|
284 |
+
'key' => '_featured',
|
285 |
+
'value' => 'yes'
|
286 |
+
);
|
287 |
+
}
|
288 |
+
|
289 |
+
if ( $members_only === 'true' || $members_only === true ) {
|
290 |
+
$args['meta_query'][] = array(
|
291 |
+
'key' => '_members_only',
|
292 |
+
'value' => 'yes'
|
293 |
+
);
|
294 |
+
}
|
295 |
+
|
296 |
+
ob_start();
|
297 |
+
|
298 |
+
$downloads = new WP_Query( $args );
|
299 |
+
|
300 |
+
if ( $downloads->have_posts() ) : ?>
|
301 |
+
|
302 |
+
<?php echo html_entity_decode( $loop_start ); ?>
|
303 |
+
|
304 |
+
<?php while ( $downloads->have_posts() ) : $downloads->the_post(); ?>
|
305 |
+
|
306 |
+
<?php echo html_entity_decode( $before ); ?>
|
307 |
+
|
308 |
+
<?php $download_monitor->get_template_part( 'content-download', $template ); ?>
|
309 |
+
|
310 |
+
<?php echo html_entity_decode( $after ); ?>
|
311 |
+
|
312 |
+
<?php endwhile; // end of the loop. ?>
|
313 |
+
|
314 |
+
<?php echo html_entity_decode( $loop_end ); ?>
|
315 |
+
|
316 |
+
<?php endif;
|
317 |
+
|
318 |
+
wp_reset_postdata();
|
319 |
+
|
320 |
+
return ob_get_clean();
|
321 |
+
}
|
322 |
+
}
|
323 |
+
|
324 |
+
new DLM_Shortcodes();
|
includes/widgets/class-dlm-widget-downloads.php
ADDED
@@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
|
4 |
+
|
5 |
+
/**
|
6 |
+
* DLM_Widget_Downloads class.
|
7 |
+
*
|
8 |
+
* @extends WP_Widget
|
9 |
+
*/
|
10 |
+
class DLM_Widget_Downloads extends WP_Widget {
|
11 |
+
|
12 |
+
var $widget_cssclass;
|
13 |
+
var $widget_description;
|
14 |
+
var $widget_idbase;
|
15 |
+
var $widget_name;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* constructor
|
19 |
+
*
|
20 |
+
* @access public
|
21 |
+
* @return void
|
22 |
+
*/
|
23 |
+
function DLM_Widget_Downloads() {
|
24 |
+
|
25 |
+
/* Widget variable settings. */
|
26 |
+
$this->widget_cssclass = 'dlm_widget_downloads';
|
27 |
+
$this->widget_description = __( 'Display a list of your downloads.', 'download_monitor' );
|
28 |
+
$this->widget_idbase = 'dlm_widget_downloads';
|
29 |
+
$this->widget_name = __( 'Downloads List', 'download_monitor' );
|
30 |
+
|
31 |
+
/* Widget settings. */
|
32 |
+
$widget_ops = array( 'classname' => $this->widget_cssclass, 'description' => $this->widget_description );
|
33 |
+
|
34 |
+
/* Create the widget. */
|
35 |
+
$this->WP_Widget( 'dlm_widget_downloads', $this->widget_name, $widget_ops );
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* widget function.
|
40 |
+
*
|
41 |
+
* @see WP_Widget
|
42 |
+
* @access public
|
43 |
+
* @param array $args
|
44 |
+
* @param array $instance
|
45 |
+
* @return void
|
46 |
+
*/
|
47 |
+
function widget( $args, $instance ) {
|
48 |
+
global $download_monitor;
|
49 |
+
|
50 |
+
extract( $args );
|
51 |
+
|
52 |
+
$title = isset( $instance['title'] ) ? apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) : __( 'Featured Downloads', 'download_monitor' );
|
53 |
+
$posts_per_page = isset( $instance['posts_per_page'] ) ? absint( $instance['posts_per_page'] ) : 10;
|
54 |
+
$format = isset( $instance['format'] ) ? sanitize_title( $instance['format'] ) : '';
|
55 |
+
$orderby = isset( $instance['orderby'] ) ? $instance['orderby'] : 'title';
|
56 |
+
$order = isset( $instance['order'] ) ? $instance['order'] : 'ASC';
|
57 |
+
$featured = isset( $instance['featured'] ) ? $instance['featured'] : 'no';
|
58 |
+
$members_only = isset( $instance['members_only'] ) ? $instance['members_only'] : 'no';
|
59 |
+
|
60 |
+
$args = array(
|
61 |
+
'post_status' => 'publish',
|
62 |
+
'post_type' => 'dlm_download',
|
63 |
+
'no_found_rows' => 1,
|
64 |
+
'posts_per_page' => $posts_per_page,
|
65 |
+
'orderby' => $orderby,
|
66 |
+
'order' => $order,
|
67 |
+
'meta_query' => array(),
|
68 |
+
'tax_query' => array()
|
69 |
+
);
|
70 |
+
|
71 |
+
if ( $orderby == 'download_count' ) {
|
72 |
+
$args['orderby'] = 'meta_value';
|
73 |
+
$args['meta_key'] = '_download_count';
|
74 |
+
}
|
75 |
+
|
76 |
+
if ( $featured == 'yes' ) {
|
77 |
+
$args['meta_query'][] = array(
|
78 |
+
'key' => '_featured',
|
79 |
+
'value' => 'yes'
|
80 |
+
);
|
81 |
+
}
|
82 |
+
|
83 |
+
if ( $members_only == 'yes' ) {
|
84 |
+
$args['meta_query'][] = array(
|
85 |
+
'key' => '_members_only',
|
86 |
+
'value' => 'yes'
|
87 |
+
);
|
88 |
+
}
|
89 |
+
|
90 |
+
$r = new WP_Query( $args );
|
91 |
+
|
92 |
+
if ( $r->have_posts() ) {
|
93 |
+
|
94 |
+
echo $before_widget;
|
95 |
+
|
96 |
+
if ( $title )
|
97 |
+
echo $before_title . $title . $after_title;
|
98 |
+
|
99 |
+
echo apply_filters( 'dlm_widget_downloads_list_start', '<ul class="dlm-downloads">' );
|
100 |
+
|
101 |
+
while ( $r->have_posts()) {
|
102 |
+
$r->the_post();
|
103 |
+
|
104 |
+
echo apply_filters( 'dlm_widget_downloads_list_item_start', '<li>' );
|
105 |
+
|
106 |
+
$download_monitor->get_template_part( 'content-download', $format );
|
107 |
+
|
108 |
+
echo apply_filters( 'dlm_widget_downloads_list_item_end', '</li>' );
|
109 |
+
}
|
110 |
+
|
111 |
+
echo apply_filters( 'dlm_widget_downloads_list_end', '</ul>' );
|
112 |
+
|
113 |
+
echo $after_widget;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* update function.
|
119 |
+
*
|
120 |
+
* @see WP_Widget->update
|
121 |
+
* @access public
|
122 |
+
* @param array $new_instance
|
123 |
+
* @param array $old_instance
|
124 |
+
* @return array
|
125 |
+
*/
|
126 |
+
function update( $new_instance, $old_instance ) {
|
127 |
+
$instance = $old_instance;
|
128 |
+
$instance['title'] = strip_tags( $new_instance['title'] );
|
129 |
+
$instance['posts_per_page'] = absint( $new_instance['posts_per_page'] );
|
130 |
+
$instance['format'] = sanitize_title( $new_instance['format'] );
|
131 |
+
$instance['orderby'] = sanitize_text_field( $new_instance['orderby'] );
|
132 |
+
$instance['order'] = sanitize_text_field( $new_instance['order'] );
|
133 |
+
$instance['featured'] = isset( $new_instance['featured'] ) ? 'yes' : 'no';
|
134 |
+
$instance['members_only'] = isset( $new_instance['members_only'] ) ? 'yes' : 'no';
|
135 |
+
|
136 |
+
return $instance;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* form function.
|
141 |
+
*
|
142 |
+
* @see WP_Widget->form
|
143 |
+
* @access public
|
144 |
+
* @param array $instance
|
145 |
+
* @return void
|
146 |
+
*/
|
147 |
+
function form( $instance ) {
|
148 |
+
$title = isset( $instance['title'] ) ? $instance['title'] : __( 'Featured Downloads', 'download_monitor' );
|
149 |
+
$posts_per_page = isset( $instance['posts_per_page'] ) ? absint( $instance['posts_per_page'] ) : 10;
|
150 |
+
$format = isset( $instance['format'] ) ? sanitize_title( $instance['format'] ) : '';
|
151 |
+
$orderby = isset( $instance['orderby'] ) ? $instance['orderby'] : 'title';
|
152 |
+
$order = isset( $instance['order'] ) ? $instance['order'] : 'ASC';
|
153 |
+
$featured = isset( $instance['featured'] ) ? $instance['featured'] : 'no';
|
154 |
+
$members_only = isset( $instance['members_only'] ) ? $instance['members_only'] : 'no';
|
155 |
+
?>
|
156 |
+
<p>
|
157 |
+
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'download_monitor' ); ?></label>
|
158 |
+
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
|
159 |
+
</p>
|
160 |
+
<p>
|
161 |
+
<label for="<?php echo $this->get_field_id( 'posts_per_page' ); ?>"><?php _e( 'Limit:', 'download_monitor' ); ?></label>
|
162 |
+
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'posts_per_page' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'posts_per_page' ) ); ?>" type="text" value="<?php echo esc_attr( $posts_per_page ); ?>" size="3" />
|
163 |
+
</p>
|
164 |
+
<p>
|
165 |
+
<label for="<?php echo $this->get_field_id( 'format' ); ?>"><?php _e( 'Output template:', 'download_monitor' ); ?></label>
|
166 |
+
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'format' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'format' ) ); ?>" type="text" value="<?php echo esc_attr( $format ); ?>" placeholder="<?php _e( 'Default template', 'download_monitor' ); ?>" />
|
167 |
+
</p>
|
168 |
+
<p>
|
169 |
+
<label for="<?php echo $this->get_field_id( 'orderby' ); ?>"><?php _e( 'Order by:', 'download_monitor' ); ?></label>
|
170 |
+
<select class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'orderby' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'orderby' ) ); ?>" type="text">
|
171 |
+
<option value="title" <?php selected( $orderby, 'title' ); ?>><?php _e( 'Title', 'download_monitor' ); ?></option>
|
172 |
+
<option value="rand" <?php selected( $orderby, 'rand' ); ?>><?php _e( 'Random', 'download_monitor' ); ?></option>
|
173 |
+
<option value="ID" <?php selected( $orderby, 'ID' ); ?>><?php _e( 'ID', 'download_monitor' ); ?></option>
|
174 |
+
<option value="date" <?php selected( $orderby, 'date' ); ?>><?php _e( 'Date added', 'download_monitor' ); ?></option>
|
175 |
+
<option value="modified" <?php selected( $orderby, 'modified' ); ?>><?php _e( 'Date modified', 'download_monitor' ); ?></option>
|
176 |
+
<option value="download_count" <?php selected( $orderby, 'download_count' ); ?>><?php _e( 'Download count', 'download_monitor' ); ?></option>
|
177 |
+
</select>
|
178 |
+
</p>
|
179 |
+
<p>
|
180 |
+
<label for="<?php echo $this->get_field_id( 'order' ); ?>"><?php _e( 'Order:', 'download_monitor' ); ?></label>
|
181 |
+
<select class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'order' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'order' ) ); ?>" type="text">
|
182 |
+
<option value="ASC" <?php selected( $order, 'ASC' ); ?>><?php _e( 'ASC', 'download_monitor' ); ?></option>
|
183 |
+
<option value="DESC" <?php selected( $order, 'DESC' ); ?>><?php _e( 'DESC', 'download_monitor' ); ?></option>
|
184 |
+
</select>
|
185 |
+
</p>
|
186 |
+
<p>
|
187 |
+
<input id="<?php echo esc_attr( $this->get_field_id( 'featured' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'featured' ) ); ?>" type="checkbox" <?php checked( $featured, 'yes' ); ?> />
|
188 |
+
<label for="<?php echo $this->get_field_id( 'featured' ); ?>"><?php _e( 'Show only featured downloads', 'download_monitor' ); ?></label>
|
189 |
+
</p>
|
190 |
+
<p>
|
191 |
+
<input id="<?php echo esc_attr( $this->get_field_id( 'members_only' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'members_only' ) ); ?>" type="checkbox" <?php checked( $members_only, 'yes' ); ?> />
|
192 |
+
<label for="<?php echo $this->get_field_id( 'members_only' ); ?>"><?php _e( 'Show only members only downloads', 'download_monitor' ); ?></label>
|
193 |
+
</p>
|
194 |
+
<?php
|
195 |
+
}
|
196 |
+
}
|
readme.txt
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Download Monitor ===
|
2 |
+
Contributors: mikejolley
|
3 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=mike.jolley@me.com&item_name=Donation+for+Download+Monitor
|
4 |
+
Tags: download, downloads, monitor, hits, download monitor, tracking, admin, count, counter, files, versions, download count, logging
|
5 |
+
Requires at least: 3.5
|
6 |
+
Tested up to: 3.5
|
7 |
+
Stable tag: 1.0.0
|
8 |
+
License: GPLv3
|
9 |
+
|
10 |
+
Download Monitor is a plugin for uploading and managing downloads, tracking downloads, and displaying links.
|
11 |
+
|
12 |
+
== Description ==
|
13 |
+
|
14 |
+
Download Monitor provides an interface for uploading and managing downloadable files (including support for multiple versions), inserting download links into posts, and logging downloads.
|
15 |
+
|
16 |
+
= Features =
|
17 |
+
|
18 |
+
* Add, edit and remove downloads from a familiar WP interface; just like posts.
|
19 |
+
* Quick-add panel for adding files whilst editing posts.
|
20 |
+
* Add multiple file versions to your downloads.
|
21 |
+
* Define alternative links (mirrors) per version.
|
22 |
+
* Categorise, tag, or add other meta to your downloads.
|
23 |
+
* Display download links on the frontend using shortcodes.
|
24 |
+
* Change the way download links get displayed via template files.
|
25 |
+
* Track downloads counts and log user download attempts.
|
26 |
+
* Member only downloads.
|
27 |
+
* Customisable endpoints for showing pretty download links.
|
28 |
+
|
29 |
+
[Read more about Download Monitor](http://mikejolley.com/projects/download-monitor/).
|
30 |
+
|
31 |
+
= Documentation =
|
32 |
+
|
33 |
+
Documentation will be maintained on the [GitHub Wiki here](https://github.com/mikejolley/download-monitor/wiki).
|
34 |
+
|
35 |
+
= Add-ons =
|
36 |
+
|
37 |
+
Add-ons, such as the __legacy importer__ and __page addon__ are listed [found here](http://mikejolley.com/projects/download-monitor/add-ons/). Take a look!
|
38 |
+
|
39 |
+
= Contributing and reporting bugs =
|
40 |
+
|
41 |
+
You can contribute code and localizations to this plugin via GitHub: [https://github.com/mikejolley/download-monitor](https://github.com/mikejolley/download-monitor)
|
42 |
+
|
43 |
+
= Support =
|
44 |
+
|
45 |
+
Use the WordPress.org forums for community support - I cannot offer support directly for free. If you spot a bug, you can of course log it on [Github](https://github.com/mikejolley/download-monitor) instead where I can act upon it more efficiently.
|
46 |
+
|
47 |
+
If you want help with a customisation, hire a developer!
|
48 |
+
|
49 |
+
== Installation ==
|
50 |
+
|
51 |
+
= Automatic installation =
|
52 |
+
|
53 |
+
Automatic installation is the easiest option as WordPress handles the file transfers itself and you don't even need to leave your web browser. To do an automatic install, log in to your WordPress admin panel, navigate to the Plugins menu and click Add New.
|
54 |
+
|
55 |
+
In the search field type "Download Monitor" and click Search Plugins. Once you've found the plugin you can view details about it such as the the point release, rating and description. Most importantly of course, you can install it by clicking _Install Now_.
|
56 |
+
|
57 |
+
= Manual installation =
|
58 |
+
|
59 |
+
The manual installation method involves downloading the plugin and uploading it to your webserver via your favourite FTP application.
|
60 |
+
|
61 |
+
* Download the plugin file to your computer and unzip it
|
62 |
+
* Using an FTP program, or your hosting control panel, upload the unzipped plugin folder to your WordPress installation's `wp-content/plugins/` directory.
|
63 |
+
* Activate the plugin from the Plugins menu within the WordPress admin.
|
64 |
+
|
65 |
+
== Frequently Asked Questions ==
|
66 |
+
|
67 |
+
= I used this before, so why is this version 1? =
|
68 |
+
|
69 |
+
Version 1.0.0 is a fresh start/complete rewrite of the legacy 3.0 version using modern best-practices such as custom post types and endpoints. Because of this, data from the legacy plugin won't work without migration using [the legacy importer](http://mikejolley.com/projects/download-monitor/add-ons/legacy-importer/). Since this upgrade process isn't straightforward nor automated I've reverted the version to 1.0.0 to prevent automatic updates.
|
70 |
+
|
71 |
+
Legacy versions can still be [found here](http://wordpress.org/plugins/download-monitor/developers/).
|
72 |
+
|
73 |
+
= X feature/shortcode is missing from the legacy version; why? =
|
74 |
+
|
75 |
+
The rewrite has trimmed the fat and only kept the best, most useful features. If something is missing, you can always code it yourself - the new system is very flexible and its easy to query files using [get_posts](http://codex.wordpress.org/Template_Tags/get_posts).
|
76 |
+
|
77 |
+
If you are missing the "Page Addon", this is now a separate plugin found here: [Download Monitor Page Addon](http://mikejolley.com/projects/download-monitor/add-ons/page-addon/).
|
78 |
+
|
79 |
+
= Can I upload .xxx filetype using the uploader? =
|
80 |
+
|
81 |
+
Download Monitor uses the WordPress uploader for uploading files. By default these formats are supported:
|
82 |
+
|
83 |
+
* Images - .jpg, .jpeg, .png, .gif
|
84 |
+
* Documents - .pdf, .doc, .docx, .ppt, .pptx, .pps, .ppsx, .odt, .xls, .xlsx
|
85 |
+
* Music - .mp3, .m4a, .ogg, .wav
|
86 |
+
* Video - .mp4, .m4v, .mov, .wmv, .avi, .mpg, .ogv, .3gp, .3g2
|
87 |
+
|
88 |
+
To add more you can use a plugin, or filters. This post is a good resource for doing it with filters: [Change WordPress Upload Mime Types](http://www.paulund.co.uk/change-wordpress-upload-mime-types).
|
89 |
+
|
90 |
+
= Can I link to external downloads? =
|
91 |
+
|
92 |
+
Yes, you can use both local paths and external URLs.
|
93 |
+
|
94 |
+
= My Download links 404 =
|
95 |
+
|
96 |
+
Download links are powered by endpoints. If you find them 404'ing, go to Settings > Permalinks and save. This will flush the permalinks and allow our endpoints to be added.
|
97 |
+
|
98 |
+
= Download counts are not increasing when I download something =
|
99 |
+
|
100 |
+
Admin hits are not counted, log out and try!
|
101 |
+
|
102 |
+
== Screenshots ==
|
103 |
+
|
104 |
+
1. The main admin screen lists your downloads using familiar WordPress UI.
|
105 |
+
2. Easily add file information and multiple versions.
|
106 |
+
3. The quick add panel can be opened via a link about the post editor. This lets you quickly add a file and insert it into a post.
|
107 |
+
4. Display regular download links or fancy ones all using shortcodes and templates.
|
108 |
+
|
109 |
+
== Changelog ==
|
110 |
+
|
111 |
+
= 1.0.0 =
|
112 |
+
* Complete rewrite of the plugin making use of custom post types and other best practices. Fresh start version '1' to prevent auto-updates (legacy importer needs to be used to migrate from old versions).
|
113 |
+
|
114 |
+
== Upgrade Notice ==
|
115 |
+
|
116 |
+
= 1.0.0 =
|
117 |
+
To update from legacy versions use the legacy importer](http://mikejolley.com/projects/download-monitor/add-ons/legacy-importer/).
|
templates/content-download-box.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Detailed download output
|
4 |
+
*/
|
5 |
+
|
6 |
+
global $dlm_download;
|
7 |
+
?>
|
8 |
+
<aside class="download-box">
|
9 |
+
|
10 |
+
<?php $dlm_download->the_image(); ?>
|
11 |
+
|
12 |
+
<div class="download-count"><?php printf( _n( '1 download', '%d downloads', $dlm_download->get_the_download_count(), 'download_monitor' ), $dlm_download->get_the_download_count() ) ?></div>
|
13 |
+
|
14 |
+
<div class="download-box-content">
|
15 |
+
|
16 |
+
<h1><?php $dlm_download->the_title(); ?></h1>
|
17 |
+
|
18 |
+
<?php $dlm_download->the_short_description(); ?>
|
19 |
+
|
20 |
+
<a class="download-button" title="<?php if ( $dlm_download->has_version_number() ) printf( __( 'Version %s', 'download_monitor' ), $dlm_download->get_the_version_number() ); ?>" href="<?php $dlm_download->the_download_link(); ?>" rel="nofollow">
|
21 |
+
<?php _e( 'Download File', 'download_monitor' ); ?>
|
22 |
+
<small><?php $dlm_download->the_filename(); ?> – <?php $dlm_download->the_filesize(); ?></small>
|
23 |
+
</a>
|
24 |
+
|
25 |
+
</div>
|
26 |
+
</aside>
|
27 |
+
|
28 |
+
|
templates/content-download-button.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Download button
|
4 |
+
*/
|
5 |
+
|
6 |
+
global $dlm_download, $download_monitor;
|
7 |
+
?>
|
8 |
+
<p><a class="aligncenter download-button" href="<?php $dlm_download->the_download_link(); ?>" rel="nofollow">
|
9 |
+
<?php printf( __( 'Download “%s”', 'download_monitor' ), $dlm_download->get_the_title() ); ?>
|
10 |
+
<small><?php $dlm_download->the_filename(); ?> – <?php printf( _n( 'Downloaded 1 time', 'Downloaded %d times', $dlm_download->get_the_download_count(), 'download_monitor' ), $dlm_download->get_the_download_count() ) ?> – <?php $dlm_download->the_filesize(); ?></small>
|
11 |
+
</a></p>
|
templates/content-download-filename.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Default output for a download via the [download] shortcode
|
4 |
+
*/
|
5 |
+
|
6 |
+
global $dlm_download;
|
7 |
+
?>
|
8 |
+
<a class="download-link filetype-icon <?php echo 'filetype-' . $dlm_download->get_the_filetype(); ?>" title="<?php if ( $dlm_download->has_version_number() ) printf( __( 'Version %s', 'download_monitor' ), $dlm_download->get_the_version_number() ); ?>" href="<?php $dlm_download->the_download_link(); ?>" rel="nofollow">
|
9 |
+
<?php $dlm_download->the_filename(); ?> (<?php printf( _n( '1 download', '%d downloads', $dlm_download->get_the_download_count(), 'download_monitor' ), $dlm_download->get_the_download_count() ) ?>)
|
10 |
+
</a>
|
templates/content-download.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Default output for a download via the [download] shortcode
|
4 |
+
*/
|
5 |
+
|
6 |
+
global $dlm_download;
|
7 |
+
?>
|
8 |
+
<a class="download-link" title="<?php if ( $dlm_download->has_version_number() ) printf( __( 'Version %s', 'download_monitor' ), $dlm_download->get_the_version_number() ); ?>" href="<?php $dlm_download->the_download_link(); ?>" rel="nofollow">
|
9 |
+
<?php $dlm_download->the_title(); ?> (<?php printf( _n( '1 download', '%d downloads', $dlm_download->get_the_download_count(), 'download_monitor' ), $dlm_download->get_the_download_count() ) ?>)
|
10 |
+
</a>
|