Version Description
- Fixed a possible JavaScript error if an Attachment that's an image doesn't have a proper thumbnail URL
- Added a total() method that will return the number of Attachments for the current instance
- When requesting the image() for a non-image Attachment, the WordPress-defined icon will be returned
- Added an icon() method that will return the WordPress-defined icon for the Attachment
- Cleaned up a PHP Warning when trying to save for an undefined field type
- Fixed an issue where template tags would be output for non-image Attachments after saving
Download this release
Release Info
Developer | jchristopher |
Plugin | Attachments |
Version | 3.0.6 |
Comparing to | |
See all releases |
Code changes from version 1.6.2.1 to 3.0.6
- CONTRIBUTING.md +14 -0
- README.md +302 -0
- classes/class.attachments.php +1220 -0
- classes/class.field.php +85 -0
- classes/fields/class.field.text.php +35 -0
- classes/fields/index.php +1 -0
- classes/index.php +1 -0
- css/attachments.css +166 -73
- css/index.php +5 -0
- attachments.options.php → deprecated/attachments.options.php +0 -0
- attachments.php → deprecated/attachments.php +8 -109
- deprecated/css/attachments.css +73 -0
- deprecated/css/index.php +1 -0
- deprecated/get-attachments.php +105 -0
- deprecated/images/handle.gif +0 -0
- deprecated/images/index.php +1 -0
- deprecated/index.php +1 -0
- deprecated/js/attachments.js +146 -0
- {js → deprecated/js}/handlebars.js +0 -0
- deprecated/js/index.php +1 -0
- {languages → deprecated/languages}/attachments-fr_FR.mo +0 -0
- {languages → deprecated/languages}/attachments-fr_FR.po +0 -0
- {languages → deprecated/languages}/attachments-it_IT.mo +0 -0
- {languages → deprecated/languages}/attachments-it_IT.po +0 -0
- {languages → deprecated/languages}/attachments-pl_PL.mo +0 -0
- {languages → deprecated/languages}/attachments-pl_PL.po +0 -0
- {languages → deprecated/languages}/attachments-pt_BR.mo +0 -0
- {languages → deprecated/languages}/attachments-pt_BR.po +0 -0
- {languages → deprecated/languages}/attachments-sv_SE.mo +0 -0
- {languages → deprecated/languages}/attachments-sv_SE.po +0 -0
- deprecated/languages/index.php +1 -0
- humans.txt +16 -0
- images/handle.gif +0 -0
- images/index.php +5 -0
- index.php +47 -0
- js/attachments.js +86 -142
- js/index.php +5 -0
- languages/index.php +5 -0
- license.txt +281 -0
- readme.txt +216 -34
- screenshot-1.jpg +0 -0
- screenshot-2.jpg +0 -0
- screenshot-3.jpg +0 -0
- upgrade.php +3 -0
- views/index.php +1 -0
- views/options.php +274 -0
CONTRIBUTING.md
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Contributing to Attachments development
|
2 |
+
|
3 |
+
Thank you so much for contributing to this project, I love pull requests! To effecively contribute to the development of Attachments please do the following:
|
4 |
+
|
5 |
+
1. Create a GitHub account
|
6 |
+
1. [Fork](https://help.github.com/articles/fork-a-repo) the repo
|
7 |
+
1. Create a branch from `master` with a meaningful name describing your task
|
8 |
+
1. Ensure extrenuous whitespace is removed before committing
|
9 |
+
1. Make commits of logical units
|
10 |
+
1. Ensure commit messages effectively explain everything that was changed
|
11 |
+
1. Push your changes to your branch of your fork
|
12 |
+
1. Submit a pull request
|
13 |
+
|
14 |
+
Thank you!
|
README.md
ADDED
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
This is a WordPress plugin. [Official download available on WordPress Extend](http://wordpress.org/extend/plugins/attachments/).
|
2 |
+
|
3 |
+
# Attachments
|
4 |
+
|
5 |
+
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types
|
6 |
+
|
7 |
+
* [Description](#description)
|
8 |
+
* [Installation](#installation)
|
9 |
+
* **[Upgrade Notice](#upgrade-notice)** *Pay specific attention if upgrading from a version before 3.0*
|
10 |
+
* [Usage](#usage)
|
11 |
+
* [Screenshots](#screenshots)
|
12 |
+
* [Frequently Asked Questions](#frequently-asked-questions)
|
13 |
+
* [Changelog](#changelog)
|
14 |
+
* [Roadmap](#roadmap)
|
15 |
+
|
16 |
+
## Description
|
17 |
+
|
18 |
+
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types. This plugin *does not* directly interact with your theme, you will need to edit your template files.
|
19 |
+
|
20 |
+
### Updated for WordPress 3.5!
|
21 |
+
|
22 |
+
WordPress 3.5 ships with an amazing new Media workflow and Attachments 3.0 makes great use of it. *If you are not running WordPress 3.5, version 1.6.2.1 will be used until you upgrade to WordPress 3.5.*
|
23 |
+
|
24 |
+
### Associate Media items with posts
|
25 |
+
|
26 |
+
The idea behind Attachments is to give developers the ability to directly associate Media items with any post. This is accomplished by adding a meta box to post edit screens as determined by the developer. Once Media items have been associated with a post, you're able to retrieve those Attachments and include them directly within your template files using any specific markup you wish.
|
27 |
+
|
28 |
+
### Integrate Attachments within your theme with fine grained control
|
29 |
+
|
30 |
+
**Attachments does not automatically integrate itself with your theme.** Since the idea behind Attachments is to allow integration of Media within posts using developer-crafted, unique markup, *it's up to you to integrate with your theme*. The most basic integration includes editing the [appropriate template file](http://codex.wordpress.org/Template_Hierarchy) and adding your call(s) to Attachments. For example, if you have set up Attachments to be used with your Posts entries, edit `single.php` to include the following within The Loop:
|
31 |
+
|
32 |
+
```php
|
33 |
+
<?php $attachments = new Attachments( 'attachments' ); /* pass the instance name */ ?>
|
34 |
+
<?php if( $attachments->exist() ) : ?>
|
35 |
+
<h3>Attachments</h3>
|
36 |
+
<ul>
|
37 |
+
<?php while( $attachments->get() ) : ?>
|
38 |
+
<li>
|
39 |
+
ID: <?php echo $attachments->id(); ?><br />
|
40 |
+
Type: <?php echo $attachments->type(); ?><br />
|
41 |
+
Subtype: <?php echo $attachments->subtype(); ?><br />
|
42 |
+
URL: <?php echo $attachments->url(); ?><br />
|
43 |
+
Image: <?php echo $attachments->image( 'thumbnail' ); ?><br />
|
44 |
+
Source: <?php echo $attachments->src( 'full' ); ?><br />
|
45 |
+
Size: <?php echo $attachments->filesize(); ?><br />
|
46 |
+
Title Field: <?php echo $attachments->field( 'title' ); ?><br />
|
47 |
+
Caption Field: <?php echo $attachments->field( 'caption' ); ?>
|
48 |
+
</li>
|
49 |
+
<?php endwhile; ?>
|
50 |
+
</ul>
|
51 |
+
<?php endif; ?>
|
52 |
+
```
|
53 |
+
|
54 |
+
That snippet will request all of the existing Attachments defined for the current Post within The Loop, and retrieve each itemized property for that Attachment. Using the provided details you're able to integrate the attached Media items in any way you please.
|
55 |
+
|
56 |
+
## Installation
|
57 |
+
|
58 |
+
1. Download the plugin and extract the files
|
59 |
+
1. Upload `attachments` to your `~/wp-content/plugins/` directory
|
60 |
+
1. Activate the plugin through the 'Plugins' menu in WordPress
|
61 |
+
1. Implement Attachments in your theme's `functions.php` or your own plugin (see **[Usage](#usage)**)
|
62 |
+
1. Update your templates where applicable (see **[Usage](#usage)**)
|
63 |
+
|
64 |
+
## Upgrade Notice
|
65 |
+
|
66 |
+
#### 3.0
|
67 |
+
**You will need to update your theme files that use Attachments 3.0**. Version 1.x of Attachments has been *fully deprecated* but is still available. If you would like to continue to use the (no longer supported) 1.x version you may add the following to your `wp-config.php`:
|
68 |
+
|
69 |
+
```php
|
70 |
+
define( 'ATTACHMENTS_LEGACY', true ); // force the legacy version of Attachments
|
71 |
+
```
|
72 |
+
|
73 |
+
Version 3 is a **major** rewrite. While I've taken precautions in ensuring you won't lose any saved data it is important to back up your databse prior to upgrading in case something goes wrong. This version is a complete rewrite so all legacy data will be left in place, but a migration must take place to match the new data storage model and workflow.
|
74 |
+
|
75 |
+
## Usage
|
76 |
+
|
77 |
+
When Attachments is first activated, a default instance is created titled Attachments. It has two fields:
|
78 |
+
|
79 |
+
1. Title
|
80 |
+
1. Caption
|
81 |
+
|
82 |
+
If you would like to *disable the default instance* (meta box titled 'Attachments' with a 'Title' and 'Caption' field) add the following to your `wp-config.php`:
|
83 |
+
|
84 |
+
```php
|
85 |
+
define( 'ATTACHMENTS_DEFAULT_INSTANCE', false );
|
86 |
+
```
|
87 |
+
|
88 |
+
You may create instances with your own custom fields by using the `attachments_register` action. To create your own instance add the following to your theme's `functions.php` or your own plugin:
|
89 |
+
|
90 |
+
```php
|
91 |
+
<?php
|
92 |
+
|
93 |
+
function my_attachments( $attachments )
|
94 |
+
{
|
95 |
+
$args = array(
|
96 |
+
|
97 |
+
// title of the meta box (string)
|
98 |
+
'label' => 'My Attachments',
|
99 |
+
|
100 |
+
// all post types to utilize (string|array)
|
101 |
+
'post_type' => array( 'post', 'page' ),
|
102 |
+
|
103 |
+
// allowed file type(s) (array) (image|video|text|audio|application)
|
104 |
+
'filetype' => null, // no filetype limit
|
105 |
+
|
106 |
+
// include a note within the meta box (string)
|
107 |
+
'note' => 'Attach files here!',
|
108 |
+
|
109 |
+
// text for 'Attach' button (string)
|
110 |
+
'button_text' => __( 'Attach Files', 'attachments' ),
|
111 |
+
|
112 |
+
// text for modal 'Attach' button (string)
|
113 |
+
'modal_text' => __( 'Attach', 'attachments' ),
|
114 |
+
|
115 |
+
// fields for this instance (array)
|
116 |
+
'fields' => array(
|
117 |
+
array(
|
118 |
+
'name' => 'title', // unique field name
|
119 |
+
'type' => 'text', // registered field type (field available in 3.0: text)
|
120 |
+
'label' => __( 'Title', 'attachments' ), // label to display
|
121 |
+
),
|
122 |
+
array(
|
123 |
+
'name' => 'caption', // unique field name
|
124 |
+
'type' => 'text', // registered field type (field available in 3.0: text)
|
125 |
+
'label' => __( 'Caption', 'attachments' ), // label to display
|
126 |
+
),
|
127 |
+
array(
|
128 |
+
'name' => 'copyright', // unique field name
|
129 |
+
'type' => 'text', // registered field type (field available in 3.0: text)
|
130 |
+
'label' => __( 'Copyright', 'attachments' ), // label to display
|
131 |
+
),
|
132 |
+
),
|
133 |
+
|
134 |
+
);
|
135 |
+
|
136 |
+
$attachments->register( 'my_attachments', $args ); // unique instance name
|
137 |
+
}
|
138 |
+
|
139 |
+
add_action( 'attachments_register', 'my_attachments' );
|
140 |
+
```
|
141 |
+
|
142 |
+
Once your instances are set up and working, you'll also need to edit your theme's template files to pull the data to the front end. To retrieve the Attachments for the current post, add this within The Loop:
|
143 |
+
|
144 |
+
```php
|
145 |
+
<?php $attachments = new Attachments( 'attachments' ); /* pass the instance name */ ?>
|
146 |
+
<?php if( $attachments->exist() ) : ?>
|
147 |
+
<h3>Attachments</h3>
|
148 |
+
<ul>
|
149 |
+
<?php while( $attachment = $attachments->get() ) : ?>
|
150 |
+
<li>
|
151 |
+
<pre><?php print_r( $attachment ); ?></pre>
|
152 |
+
</li>
|
153 |
+
<?php endwhile; ?>
|
154 |
+
</ul>
|
155 |
+
<?php endif; ?>
|
156 |
+
```
|
157 |
+
|
158 |
+
If you want to get the Attachments for a post **outside The Loop**, add a second parameter with the post ID when instantiating Attachments:
|
159 |
+
|
160 |
+
```php
|
161 |
+
<?php
|
162 |
+
// retrieve all Attachments for the 'attachments' instance of post 123
|
163 |
+
$attachments = new Attachments( 'attachments', 123 );
|
164 |
+
?>
|
165 |
+
<?php if( $attachments->exist() ) : ?>
|
166 |
+
<h3>Attachments</h3>
|
167 |
+
<ul>
|
168 |
+
<?php while( $attachment = $attachments->get() ) : ?>
|
169 |
+
<li>
|
170 |
+
<pre><?php print_r( $attachment ); ?></pre>
|
171 |
+
</li>
|
172 |
+
<?php endwhile; ?>
|
173 |
+
</ul>
|
174 |
+
<?php endif; ?>
|
175 |
+
```
|
176 |
+
|
177 |
+
You can also retrieve various attributes of the current Attachment directly using these utility functions:
|
178 |
+
|
179 |
+
```php
|
180 |
+
<?php $attachments = new Attachments( 'attachments' ); ?>
|
181 |
+
<?php if( $attachments->exist() ) : ?>
|
182 |
+
<h3>Attachments</h3>
|
183 |
+
<p>Total Attachments: <?php echo $attachments->total(); ?></p>
|
184 |
+
<ul>
|
185 |
+
<?php while( $attachments->get() ) : ?>
|
186 |
+
<li>
|
187 |
+
ID: <?php echo $attachments->id(); ?><br />
|
188 |
+
Type: <?php echo $attachments->type(); ?><br />
|
189 |
+
Subtype: <?php echo $attachments->subtype(); ?><br />
|
190 |
+
URL: <?php echo $attachments->url(); ?><br />
|
191 |
+
Image: <?php echo $attachments->image( 'thumbnail' ); ?><br />
|
192 |
+
Source: <?php echo $attachments->src( 'full' ); ?><br />
|
193 |
+
Size: <?php echo $attachments->filesize(); ?><br />
|
194 |
+
Title Field: <?php echo $attachments->field( 'title' ); ?><br />
|
195 |
+
Caption Field: Name: <?php echo $attachments->field( 'caption' ); ?>
|
196 |
+
</li>
|
197 |
+
<?php endwhile; ?>
|
198 |
+
</ul>
|
199 |
+
<?php endif; ?>
|
200 |
+
```
|
201 |
+
|
202 |
+
## Screenshots
|
203 |
+
|
204 |
+
##### An Attachments meta box sitting below the content editor
|
205 |
+
![An Attachments meta box sitting below the content editor](http://mondaybynoon.com/images/attachments/screenshot-1.png)
|
206 |
+
|
207 |
+
##### Direct integration with WordPress 3.5+ Media
|
208 |
+
![Direct integration with WordPress 3.5+ Media](http://mondaybynoon.com/images/attachments/screenshot-2.png)
|
209 |
+
|
210 |
+
##### Attach multiple files at once
|
211 |
+
![Attach multiple files at once](http://mondaybynoon.com/images/attachments/screenshot-3.png)
|
212 |
+
|
213 |
+
##### Custom fields for each Attachment
|
214 |
+
![Custom fields for each Attachment](http://mondaybynoon.com/images/attachments/screenshot-4.png)
|
215 |
+
|
216 |
+
##### Drag and drop to sort
|
217 |
+
![Drag and drop to sort](http://mondaybynoon.com/images/attachments/screenshot-5.png)
|
218 |
+
|
219 |
+
## Frequently Asked Questions
|
220 |
+
|
221 |
+
#### Attachments isn't showing up on my edit screens
|
222 |
+
|
223 |
+
You will need to tell Attachments which instances you'd like to use. Please reference the **[Usage](#usage)** instructions.
|
224 |
+
|
225 |
+
#### Attachments are not showing up in my theme
|
226 |
+
|
227 |
+
You will need to edit your theme files where applicable. Please reference the **[Usage](#usage)** instructions.
|
228 |
+
|
229 |
+
#### How do I disable the default Attachments meta box?
|
230 |
+
|
231 |
+
You will need to edit your Attachments configuration. Please reference the **[Usage](#usage)** instructions.
|
232 |
+
|
233 |
+
#### How do I change the fields for each Attachment?
|
234 |
+
|
235 |
+
You will need to edit your Attachments configuration. Please reference the **[Usage](#usage)** instructions.
|
236 |
+
|
237 |
+
#### Where are uploads saved?
|
238 |
+
|
239 |
+
Attachments uses WordPress' built in Media library for uploads and storage.
|
240 |
+
|
241 |
+
#### I lost my Attachments after upgrading!
|
242 |
+
|
243 |
+
***DO NOT update any Post/Page/CPT with Attachments***, the data has not been lost. Please [contact me](http://mondaybynoon.com/contact/) to begin a bugfix
|
244 |
+
|
245 |
+
## Changelog
|
246 |
+
|
247 |
+
<dl>
|
248 |
+
|
249 |
+
<dt>3.0.6</dt>
|
250 |
+
<dd>Fixed a possible JavaScript error if an Attachment that's an image doesn't have a proper thumbnail URL</dd>
|
251 |
+
<dd>Added a total() method that will return the number of Attachments for the current instance</dd>
|
252 |
+
<dd>When requesting the image() for a non-image Attachment, the WordPress-defined icon will be returned</dd>
|
253 |
+
<dd>Added an icon() method that will return the WordPress-defined icon for the Attachment</dd>
|
254 |
+
<dd>Cleaned up a PHP Warning when trying to save for an undefined field type</dd>
|
255 |
+
<dd>Fixed an issue where template tags would be output for non-image Attachments after saving</dd>
|
256 |
+
|
257 |
+
<dt>3.0.5</dt>
|
258 |
+
<dd>Fixed a regression in handling Custom Post Type names that would too aggressively interfere with instance regustration</dd>
|
259 |
+
<dd>Fixed an issue when working with non-image Attachments</dd>
|
260 |
+
|
261 |
+
<dt>3.0.4</dt>
|
262 |
+
<dd>Fixed an issue that prevented the choosing of a Featured Image for a Custom Post Type if Attachments was activated</dd>
|
263 |
+
<dd>Attachments now only enqueues its assets on edit screens that actually utilize Attachments</dd>
|
264 |
+
<dd>Fixed a potential JavaScript error triggered when a 'thumbnail' image size was not available</dd>
|
265 |
+
<dd>Prevented incorrect usage of dashes used in CPT names for post_type argument when registering Attachments instances (fixes an integration issue with WP e-Commerce)</dd>
|
266 |
+
<dd>Prevented re-running of migration process to avoid duplicates (e.g. on browser reload)</dd>
|
267 |
+
|
268 |
+
<dt>3.0.3</dt>
|
269 |
+
<dd>Fixed an issue that prevented defining a post ID when retrieving Attachments outside The Loop</dd>
|
270 |
+
<dd>Cleaned up potential PHP warning when Attachments were requested for a post that had none</dd>
|
271 |
+
|
272 |
+
<dt>3.0.2</dt>
|
273 |
+
<dd>Fixed an issue where some HTML entities were not properly stored</dd>
|
274 |
+
|
275 |
+
<dt>3.0.1</dt>
|
276 |
+
<dd>Fixed an issue where legacy mode was always enabled</dd>
|
277 |
+
|
278 |
+
<dt>3.0</dt>
|
279 |
+
<dd> <strong>Major</strong> rewrite. After three years of development, Attachments has been rewritten to make
|
280 |
+
even better use of what WordPress has to offer</dd>
|
281 |
+
<dd> Utilizes the brand spanking new 3.5 Media workflow</dd>
|
282 |
+
<dd> Configuration now takes place within your theme or a plugin</dd>
|
283 |
+
<dd> Multiple meta boxes! You can segment groups of Attachments with new instances, each unique</dd>
|
284 |
+
<dd> Dynamic fields! You can manipulate which fields each instance uses</dd>
|
285 |
+
<dd> File type limits. Limit which files are available to Attachments (e.g. images, audio, video)</dd>
|
286 |
+
|
287 |
+
</dl>
|
288 |
+
|
289 |
+
## Roadmap
|
290 |
+
|
291 |
+
Planned feature additions include:
|
292 |
+
|
293 |
+
* Additional field type: textarea
|
294 |
+
* Additional field type: WYSIWYG
|
295 |
+
* Additional field type: checkbox
|
296 |
+
* Additional field type: radio
|
297 |
+
* Additional field type: select
|
298 |
+
* User-defined limiting the number of Attachments per instance
|
299 |
+
* User-defined custom field types
|
300 |
+
* Additional hooks/actions from top to bottom
|
301 |
+
* Shortcode(s)
|
302 |
+
* Output templates
|
classes/class.attachments.php
ADDED
@@ -0,0 +1,1220 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Attachments
|
5 |
+
*
|
6 |
+
* Attachments allows you to simply append any number of items from your WordPress
|
7 |
+
* Media Library to Posts, Pages, and Custom Post Types
|
8 |
+
*
|
9 |
+
* @package Attachments
|
10 |
+
* @subpackage Main
|
11 |
+
*/
|
12 |
+
|
13 |
+
// Exit if accessed directly
|
14 |
+
if( !defined( 'ABSPATH' ) ) exit;
|
15 |
+
|
16 |
+
// Declare our class
|
17 |
+
if ( !class_exists( 'Attachments' ) ) :
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Main Attachments Class
|
21 |
+
*
|
22 |
+
* @since 3.0
|
23 |
+
*/
|
24 |
+
|
25 |
+
class Attachments {
|
26 |
+
|
27 |
+
private $version; // stores Attachments' version number
|
28 |
+
private $url; // stores Attachments' URL
|
29 |
+
private $dir; // stores Attachments' directory
|
30 |
+
private $instances; // all registered Attachments instances
|
31 |
+
private $instances_for_post_type; // instance names that apply to the current post type
|
32 |
+
private $fields; // stores all registered field types
|
33 |
+
private $attachments; // stores all of the Attachments for the given instance
|
34 |
+
|
35 |
+
private $image_sizes = array( 'full' ); // store all registered image sizes
|
36 |
+
private $default_instance = true; // use the default instance?
|
37 |
+
private $attachments_ref = -1; // flags where a get() loop last did it's thing
|
38 |
+
private $meta_key = 'attachments'; // our meta key
|
39 |
+
private $valid_filetypes = array( // what WordPress considers to be valid file types
|
40 |
+
'image',
|
41 |
+
'video',
|
42 |
+
'text',
|
43 |
+
'audio',
|
44 |
+
'application'
|
45 |
+
);
|
46 |
+
|
47 |
+
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Constructor
|
51 |
+
*
|
52 |
+
* @since 3.0
|
53 |
+
*/
|
54 |
+
function __construct( $instance = null, $post_id = null )
|
55 |
+
{
|
56 |
+
global $_wp_additional_image_sizes;
|
57 |
+
|
58 |
+
// establish our environment variables
|
59 |
+
$this->version = '3.0.6';
|
60 |
+
$this->url = ATTACHMENTS_URL;
|
61 |
+
$this->dir = ATTACHMENTS_DIR;
|
62 |
+
|
63 |
+
// includes
|
64 |
+
include_once( ATTACHMENTS_DIR . 'upgrade.php' );
|
65 |
+
include_once( ATTACHMENTS_DIR . '/classes/class.field.php' );
|
66 |
+
|
67 |
+
// deal with our legacy issues if the user hasn't dismissed or migrated already
|
68 |
+
if( false == get_option( 'attachments_migrated' ) && false == get_option( 'attachments_ignore_migration' ) )
|
69 |
+
{
|
70 |
+
$legacy = new WP_Query( 'post_type=any&post_status=any&posts_per_page=1&meta_key=_attachments' );
|
71 |
+
$this->legacy = empty( $legacy->found_posts ) ? false : true;
|
72 |
+
}
|
73 |
+
else
|
74 |
+
{
|
75 |
+
$this->legacy = false;
|
76 |
+
}
|
77 |
+
|
78 |
+
// set our image sizes
|
79 |
+
$this->image_sizes = array_merge( $this->image_sizes, get_intermediate_image_sizes() );
|
80 |
+
|
81 |
+
// include our fields
|
82 |
+
$this->fields = $this->get_field_types();
|
83 |
+
|
84 |
+
// hook into WP
|
85 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'assets' ), 999, 1 );
|
86 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'admin_pointer' ), 999 );
|
87 |
+
|
88 |
+
// register our user-defined instances
|
89 |
+
add_action( 'init', array( $this, 'do_actions_filters' ) );
|
90 |
+
|
91 |
+
// determine which instances apply to the current post type
|
92 |
+
add_action( 'init', array( $this, 'set_instances_for_current_post_type' ), 999 );
|
93 |
+
|
94 |
+
add_action( 'add_meta_boxes', array( $this, 'meta_box_init' ) );
|
95 |
+
|
96 |
+
add_action( 'admin_footer', array( $this, 'admin_footer' ) );
|
97 |
+
|
98 |
+
add_action( 'save_post', array( $this, 'save' ) );
|
99 |
+
|
100 |
+
add_action( 'admin_menu', array( $this, 'admin_page' ) );
|
101 |
+
|
102 |
+
// with version 3 we'll be giving at least one admin notice
|
103 |
+
add_action( 'admin_notices', array( $this, 'admin_notice' ) );
|
104 |
+
|
105 |
+
// set our attachments if necessary
|
106 |
+
if( !is_null( $instance ) )
|
107 |
+
$this->attachments = $this->get_attachments( $instance, $post_id );
|
108 |
+
}
|
109 |
+
|
110 |
+
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Returns whether or not the current object has any Attachments
|
114 |
+
*
|
115 |
+
* @since 3.0
|
116 |
+
*/
|
117 |
+
function exist()
|
118 |
+
{
|
119 |
+
return !empty( $this->attachments );
|
120 |
+
}
|
121 |
+
|
122 |
+
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Returns the number of Attachments
|
126 |
+
*
|
127 |
+
* @since 3.0.6
|
128 |
+
*/
|
129 |
+
function total()
|
130 |
+
{
|
131 |
+
return count( $this->attachments );
|
132 |
+
}
|
133 |
+
|
134 |
+
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Returns the next Attachment for the current object and increments the index
|
138 |
+
*
|
139 |
+
* @since 3.0
|
140 |
+
*/
|
141 |
+
function get()
|
142 |
+
{
|
143 |
+
$this->attachments_ref++;
|
144 |
+
|
145 |
+
if( !count( $this->attachments ) || $this->attachments_ref >= count( $this->attachments ) )
|
146 |
+
return false;
|
147 |
+
|
148 |
+
return $this->attachments[$this->attachments_ref];
|
149 |
+
}
|
150 |
+
|
151 |
+
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Returns the asset (array) for the current Attachment
|
155 |
+
*
|
156 |
+
* @since 3.0.6
|
157 |
+
*/
|
158 |
+
function asset( $size = 'thumbnail' )
|
159 |
+
{
|
160 |
+
// do we have our meta yet?
|
161 |
+
if( !isset( $this->attachments[$this->attachments_ref]->meta ) )
|
162 |
+
$this->attachments[$this->attachments_ref]->meta = wp_get_attachment_metadata( $this->attachments[$this->attachments_ref]->id );
|
163 |
+
|
164 |
+
// is it an image?
|
165 |
+
if(
|
166 |
+
isset( $this->attachments[$this->attachments_ref]->meta['sizes'] ) && // is it an image?
|
167 |
+
in_array( $size, $this->image_sizes ) ) // do we have the right size?
|
168 |
+
{
|
169 |
+
$asset = wp_get_attachment_image_src( $this->attachments[$this->attachments_ref]->id, $size );
|
170 |
+
}
|
171 |
+
else
|
172 |
+
{
|
173 |
+
// either it's not an image or we don't have the proper size, so we'll use the icon
|
174 |
+
$asset = $this->icon();
|
175 |
+
}
|
176 |
+
|
177 |
+
return $asset;
|
178 |
+
}
|
179 |
+
|
180 |
+
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Returns the icon (array) for the current Attachment
|
184 |
+
*
|
185 |
+
* @since 3.0.6
|
186 |
+
*/
|
187 |
+
function icon()
|
188 |
+
{
|
189 |
+
$asset = wp_get_attachment_image_src( $this->attachments[$this->attachments_ref]->id, null, true );
|
190 |
+
return $asset;
|
191 |
+
}
|
192 |
+
|
193 |
+
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Returns an appropriate <img /> for the current Attachment if it's an image
|
197 |
+
*
|
198 |
+
* @since 3.0
|
199 |
+
*/
|
200 |
+
function image( $size = 'thumbnail' )
|
201 |
+
{
|
202 |
+
$asset = $this->asset( $size );
|
203 |
+
|
204 |
+
$image_src = $asset[0];
|
205 |
+
$image_width = $asset[1];
|
206 |
+
$image_height = $asset[2];
|
207 |
+
$image_alt = get_post_meta( $this->attachments[$this->attachments_ref]->id, '_wp_attachment_image_alt', true );
|
208 |
+
|
209 |
+
$image = '<img src="' . $image_src . '" width="' . $image_width . '" height="' . $image_height . '" alt="' . $image_alt . '" />';
|
210 |
+
|
211 |
+
return $image;
|
212 |
+
}
|
213 |
+
|
214 |
+
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Returns the URL for the current Attachment if it's an image
|
218 |
+
*
|
219 |
+
* @since 3.0
|
220 |
+
*/
|
221 |
+
function src( $size = 'thumbnail' )
|
222 |
+
{
|
223 |
+
$asset = $this->asset( $size );
|
224 |
+
return $asset[0];
|
225 |
+
}
|
226 |
+
|
227 |
+
|
228 |
+
|
229 |
+
/**
|
230 |
+
* Returns the formatted filesize of the current Attachment
|
231 |
+
*
|
232 |
+
* @since 3.0
|
233 |
+
*/
|
234 |
+
function filesize()
|
235 |
+
{
|
236 |
+
if( !isset( $this->attachments[$this->attachments_ref]->id ) )
|
237 |
+
return false;
|
238 |
+
|
239 |
+
$url = wp_get_attachment_url( $this->attachments[$this->attachments_ref]->id );
|
240 |
+
$uploads = wp_upload_dir();
|
241 |
+
$file_path = str_replace( $uploads['baseurl'], $uploads['basedir'], $url );
|
242 |
+
|
243 |
+
$formatted = '0 bytes';
|
244 |
+
if( file_exists( $file_path ) )
|
245 |
+
{
|
246 |
+
$formatted = size_format( @filesize( $file_path ) );
|
247 |
+
}
|
248 |
+
return $formatted;
|
249 |
+
}
|
250 |
+
|
251 |
+
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Returns the type of the current Attachment
|
255 |
+
*
|
256 |
+
* @since 3.0
|
257 |
+
*/
|
258 |
+
function type()
|
259 |
+
{
|
260 |
+
if( !isset( $this->attachments[$this->attachments_ref]->id ) )
|
261 |
+
return false;
|
262 |
+
|
263 |
+
$attachment_mime = explode( '/', get_post_mime_type( $this->attachments[$this->attachments_ref]->id ) );
|
264 |
+
return isset( $attachment_mime[0] ) ? $attachment_mime[0] : null;
|
265 |
+
}
|
266 |
+
|
267 |
+
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Returns the subtype of the current Attachment
|
271 |
+
*
|
272 |
+
* @since 3.0
|
273 |
+
*/
|
274 |
+
function subtype()
|
275 |
+
{
|
276 |
+
if( !isset( $this->attachments[$this->attachments_ref]->id ) )
|
277 |
+
return false;
|
278 |
+
|
279 |
+
$attachment_mime = explode( '/', get_post_mime_type( $this->attachments[$this->attachments_ref]->id ) );
|
280 |
+
return isset( $attachment_mime[1] ) ? $attachment_mime[1] : null;
|
281 |
+
}
|
282 |
+
|
283 |
+
|
284 |
+
|
285 |
+
/**
|
286 |
+
* Returns the id of the current Attachment
|
287 |
+
*
|
288 |
+
* @since 3.0
|
289 |
+
*/
|
290 |
+
function id()
|
291 |
+
{
|
292 |
+
return isset( $this->attachments[$this->attachments_ref]->id ) ? $this->attachments[$this->attachments_ref]->id : null;
|
293 |
+
}
|
294 |
+
|
295 |
+
|
296 |
+
|
297 |
+
/**
|
298 |
+
* Returns the URL for the current Attachment
|
299 |
+
*
|
300 |
+
* @since 3.0
|
301 |
+
*/
|
302 |
+
function url()
|
303 |
+
{
|
304 |
+
if( !isset( $this->attachments[$this->attachments_ref]->id ) )
|
305 |
+
return false;
|
306 |
+
|
307 |
+
return wp_get_attachment_url( $this->attachments[$this->attachments_ref]->id );
|
308 |
+
}
|
309 |
+
|
310 |
+
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Returns the field value for the submitted field name
|
314 |
+
*
|
315 |
+
* @since 3.0
|
316 |
+
*/
|
317 |
+
function field( $name = 'title' )
|
318 |
+
{
|
319 |
+
return isset( $this->attachments[$this->attachments_ref]->fields->$name ) ? $this->attachments[$this->attachments_ref]->fields->$name : false;
|
320 |
+
}
|
321 |
+
|
322 |
+
|
323 |
+
|
324 |
+
/**
|
325 |
+
* Fires all of our actions
|
326 |
+
*
|
327 |
+
* @since 3.0
|
328 |
+
*/
|
329 |
+
function do_actions_filters()
|
330 |
+
{
|
331 |
+
// implement our default instance if appropriate
|
332 |
+
if( !defined( 'ATTACHMENTS_DEFAULT_INSTANCE' ) )
|
333 |
+
$this->register();
|
334 |
+
|
335 |
+
// facilitate user-defined instance registration
|
336 |
+
do_action( 'attachments_register', $this );
|
337 |
+
}
|
338 |
+
|
339 |
+
|
340 |
+
|
341 |
+
/**
|
342 |
+
* Enqueues our necessary assets
|
343 |
+
*
|
344 |
+
* @since 3.0
|
345 |
+
*/
|
346 |
+
function assets( $hook )
|
347 |
+
{
|
348 |
+
global $post;
|
349 |
+
|
350 |
+
// we only want our assets on edit screens
|
351 |
+
if( !empty( $this->instances_for_post_type ) && 'edit.php' != $hook && 'post.php' != $hook && 'post-new.php' != $hook )
|
352 |
+
return;
|
353 |
+
|
354 |
+
// we only want to enqueue if appropriate
|
355 |
+
if( empty( $this->instances_for_post_type ) )
|
356 |
+
return;
|
357 |
+
|
358 |
+
$post_id = isset( $post->ID ) ? $post->ID : null;
|
359 |
+
wp_enqueue_media( array( 'post' => $post_id ) );
|
360 |
+
|
361 |
+
wp_enqueue_style( 'attachments', trailingslashit( $this->url ) . 'css/attachments.css', null, $this->version, 'screen' );
|
362 |
+
|
363 |
+
wp_enqueue_script( 'attachments', trailingslashit( $this->url ) . 'js/attachments.js', array( 'jquery', 'jquery-ui-sortable' ), $this->version, true );
|
364 |
+
}
|
365 |
+
|
366 |
+
|
367 |
+
|
368 |
+
/**
|
369 |
+
* Registers meta box(es) for the current edit screen
|
370 |
+
*
|
371 |
+
* @since 3.0
|
372 |
+
*/
|
373 |
+
function meta_box_init()
|
374 |
+
{
|
375 |
+
$nonce_sent = false;
|
376 |
+
|
377 |
+
if( !empty( $this->instances_for_post_type ) )
|
378 |
+
{
|
379 |
+
foreach( $this->instances_for_post_type as $instance )
|
380 |
+
{
|
381 |
+
$instance_name = $instance;
|
382 |
+
$instance = (object) $this->instances[$instance];
|
383 |
+
$instance->name = $instance_name;
|
384 |
+
|
385 |
+
add_meta_box( 'attachments-' . $instance_name, __( esc_attr( $instance->label ) ), array( $this, 'meta_box_markup' ), $this->get_post_type(), 'normal', 'high', array( 'instance' => $instance, 'setup_nonce' => !$nonce_sent ) );
|
386 |
+
|
387 |
+
$nonce_sent = true;
|
388 |
+
}
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
|
393 |
+
|
394 |
+
/**
|
395 |
+
* Callback that outputs the meta box markup
|
396 |
+
*
|
397 |
+
* @since 3.0
|
398 |
+
*/
|
399 |
+
function meta_box_markup( $post, $metabox )
|
400 |
+
{
|
401 |
+
// single out our $instance
|
402 |
+
$instance = (object) $metabox['args']['instance'];
|
403 |
+
|
404 |
+
if( $metabox['args']['setup_nonce'] )
|
405 |
+
wp_nonce_field( 'attachments_save', 'attachments_nonce' );
|
406 |
+
|
407 |
+
?>
|
408 |
+
|
409 |
+
<div id="attachments-<?php echo $instance->name; ?>">
|
410 |
+
<?php if( !empty( $instance->note ) ) : ?>
|
411 |
+
<div class="attachments-note"><?php echo apply_filters( 'the_content', $instance->note ); ?></div>
|
412 |
+
<?php endif; ?>
|
413 |
+
<div class="attachments-container attachments-<?php echo $instance->name; ?>"><?php
|
414 |
+
if( isset( $instance->attachments ) && !empty( $instance->attachments ) )
|
415 |
+
{
|
416 |
+
foreach( $instance->attachments as $attachment )
|
417 |
+
{
|
418 |
+
// we need to give our Attachment a uid to carry through to all the fields
|
419 |
+
$attachment->uid = uniqid();
|
420 |
+
|
421 |
+
// we'll create the attachment
|
422 |
+
$this->create_attachment( $instance->name, $attachment );
|
423 |
+
}
|
424 |
+
}
|
425 |
+
?></div>
|
426 |
+
<div class="attachments-invoke-wrapper">
|
427 |
+
<a class="button attachments-invoke"><?php _e( esc_attr( $instance->button_text ), 'attachments' ); ?></a>
|
428 |
+
</div>
|
429 |
+
</div>
|
430 |
+
<script type="text/javascript">
|
431 |
+
jQuery(document).ready(function($){
|
432 |
+
var $element = $('#attachments-<?php echo esc_attr( $instance->name ); ?>'),
|
433 |
+
title = '<?php echo __( esc_attr( $instance->label ) ); ?>',
|
434 |
+
button = '<?php echo __( esc_attr( $instance->modal_text ) ); ?>',
|
435 |
+
attachmentsframe;
|
436 |
+
|
437 |
+
$element.on( 'click', '.attachments-invoke', function( event ) {
|
438 |
+
var options, attachment;
|
439 |
+
|
440 |
+
event.preventDefault();
|
441 |
+
|
442 |
+
// if the frame already exists, open it
|
443 |
+
if ( attachmentsframe ) {
|
444 |
+
attachmentsframe.open();
|
445 |
+
return;
|
446 |
+
}
|
447 |
+
|
448 |
+
// set our seetings
|
449 |
+
attachmentsframe = wp.media({
|
450 |
+
|
451 |
+
title: title,
|
452 |
+
|
453 |
+
<?php if( $instance->limit < 0 || $instance->limit > 1 ) : ?>
|
454 |
+
multiple: true,
|
455 |
+
<?php endif; ?>
|
456 |
+
|
457 |
+
library: {
|
458 |
+
type: '<?php echo esc_attr( implode( ",", $instance->filetype ) ); ?>'
|
459 |
+
},
|
460 |
+
|
461 |
+
// Customize the submit button.
|
462 |
+
button: {
|
463 |
+
// Set the text of the button.
|
464 |
+
text: button
|
465 |
+
}
|
466 |
+
});
|
467 |
+
|
468 |
+
// set up our select handler
|
469 |
+
attachmentsframe.on( 'select', function() {
|
470 |
+
|
471 |
+
selection = attachmentsframe.state().get('selection');
|
472 |
+
|
473 |
+
if ( ! selection )
|
474 |
+
return;
|
475 |
+
|
476 |
+
// compile our Underscore template using Mustache syntax
|
477 |
+
_.templateSettings = {
|
478 |
+
variable : 'attachments',
|
479 |
+
interpolate : /\{\{(.+?)\}\}/g
|
480 |
+
}
|
481 |
+
|
482 |
+
var template = _.template($('script#tmpl-attachments-<?php echo $instance->name; ?>').html());
|
483 |
+
|
484 |
+
// loop through the selected files
|
485 |
+
selection.each( function( attachment ) {
|
486 |
+
|
487 |
+
// set our attributes to the template
|
488 |
+
attachment.attributes.attachment_uid = attachments_uniqid( 'attachmentsjs' );
|
489 |
+
|
490 |
+
// by default use the generic icon
|
491 |
+
attachment.attributes.attachment_thumb = attachment.attributes.icon;
|
492 |
+
|
493 |
+
// only thumbnails have sizes which is what we're on the hunt for
|
494 |
+
if(attachments_isset(attachment.attributes.sizes)){
|
495 |
+
if(attachments_isset(attachment.attributes.sizes.thumbnail)){
|
496 |
+
if(attachments_isset(attachment.attributes.sizes.thumbnail.url)){
|
497 |
+
// use the thumbnail
|
498 |
+
attachment.attributes.attachment_thumb = attachment.attributes.sizes.thumbnail.url;
|
499 |
+
}
|
500 |
+
}
|
501 |
+
}
|
502 |
+
|
503 |
+
var templateData = attachment.attributes;
|
504 |
+
|
505 |
+
// append the template
|
506 |
+
$element.find('.attachments-container').append(template(templateData));
|
507 |
+
|
508 |
+
// if it wasn't an image we need to ditch the dimensions
|
509 |
+
if(!attachments_isset(attachment.attributes.width)||!attachments_isset(attachment.attributes.height)){
|
510 |
+
$element.find('.attachments-attachment:last .dimensions').hide();
|
511 |
+
}
|
512 |
+
});
|
513 |
+
});
|
514 |
+
|
515 |
+
// open the frame
|
516 |
+
attachmentsframe.open();
|
517 |
+
|
518 |
+
});
|
519 |
+
|
520 |
+
$element.on( 'click', '.delete-attachment a', function( event ) {
|
521 |
+
|
522 |
+
var targetAttachment;
|
523 |
+
|
524 |
+
event.preventDefault();
|
525 |
+
|
526 |
+
targetAttachment = $(this).parents('.attachments-attachment');
|
527 |
+
|
528 |
+
targetAttachment.slideUp(function(){
|
529 |
+
targetAttachment.remove();
|
530 |
+
});
|
531 |
+
|
532 |
+
} );
|
533 |
+
|
534 |
+
});
|
535 |
+
</script>
|
536 |
+
<?php }
|
537 |
+
|
538 |
+
|
539 |
+
|
540 |
+
/**
|
541 |
+
* Support the inclusion of custom, user-defined field types
|
542 |
+
* Borrowed implementation from Custom Field Suite by Matt Gibbs
|
543 |
+
* https://uproot.us/docs/creating-custom-field-types/
|
544 |
+
*
|
545 |
+
* @since 3.0
|
546 |
+
**/
|
547 |
+
function get_field_types()
|
548 |
+
{
|
549 |
+
$field_types = array(
|
550 |
+
'text' => ATTACHMENTS_DIR . 'classes/fields/class.field.text.php'
|
551 |
+
);
|
552 |
+
|
553 |
+
// support custom field types
|
554 |
+
// $field_types = apply_filters( 'attachments_fields', $field_types );
|
555 |
+
|
556 |
+
foreach( $field_types as $type => $path )
|
557 |
+
{
|
558 |
+
// store the registered classes so we can single out what gets added
|
559 |
+
$classes_before = get_declared_classes();
|
560 |
+
|
561 |
+
// proceed with inclusion
|
562 |
+
if( file_exists( $path ) )
|
563 |
+
{
|
564 |
+
// include the file
|
565 |
+
include_once( $path );
|
566 |
+
|
567 |
+
// determine it's class
|
568 |
+
$classes = get_declared_classes();
|
569 |
+
// the field's class is last in line
|
570 |
+
$field_class = end( $classes );
|
571 |
+
|
572 |
+
// create our link using our new field class
|
573 |
+
$field_types[$type] = $field_class;
|
574 |
+
}
|
575 |
+
}
|
576 |
+
|
577 |
+
// send it back
|
578 |
+
return $field_types;
|
579 |
+
}
|
580 |
+
|
581 |
+
|
582 |
+
|
583 |
+
/**
|
584 |
+
* Registers a field type for use within an instance
|
585 |
+
*
|
586 |
+
* @since 3.0
|
587 |
+
*/
|
588 |
+
function register_field( $params = array() )
|
589 |
+
{
|
590 |
+
$defaults = array(
|
591 |
+
'name' => 'title',
|
592 |
+
'type' => 'text',
|
593 |
+
'label' => __( 'Title', 'attachments' ),
|
594 |
+
);
|
595 |
+
|
596 |
+
$params = array_merge( $defaults, $params );
|
597 |
+
|
598 |
+
// ensure it's a valid type
|
599 |
+
if( !isset( $this->fields[$params['type']] ) )
|
600 |
+
return false;
|
601 |
+
|
602 |
+
// sanitize
|
603 |
+
if( isset( $params['name'] ) )
|
604 |
+
$params['name'] = str_replace( '-', '_', sanitize_title( $params['name'] ) );
|
605 |
+
|
606 |
+
if( isset( $params['label'] ) )
|
607 |
+
$params['label'] = __( esc_html( $params['label'] ) );
|
608 |
+
|
609 |
+
// instantiate the class for this field and send it back
|
610 |
+
return new $this->fields[ $params['type'] ]( $params['name'], $params['label'] );
|
611 |
+
}
|
612 |
+
|
613 |
+
|
614 |
+
|
615 |
+
/**
|
616 |
+
* Registers an Attachments instance
|
617 |
+
*
|
618 |
+
* @since 3.0
|
619 |
+
*/
|
620 |
+
function register( $name = 'attachments', $params = array() )
|
621 |
+
{
|
622 |
+
$defaults = array(
|
623 |
+
|
624 |
+
// title of the meta box (string)
|
625 |
+
'label' => __( 'Attachments', 'attachments' ),
|
626 |
+
|
627 |
+
// all post types to utilize (string|array)
|
628 |
+
'post_type' => array( 'post', 'page' ),
|
629 |
+
|
630 |
+
// maximum number of Attachments (int) (-1 is unlimited)
|
631 |
+
'limit' => -1,
|
632 |
+
|
633 |
+
// allowed file type(s) (array) (image|video|text|audio|application)
|
634 |
+
'filetype' => null, // no filetype limit
|
635 |
+
|
636 |
+
// include a note within the meta box (string)
|
637 |
+
'note' => null, // no note
|
638 |
+
|
639 |
+
// text for 'Attach' button (string)
|
640 |
+
'button_text' => __( 'Attach', 'attachments' ),
|
641 |
+
|
642 |
+
// text for modal 'Attach' button (string)
|
643 |
+
'modal_text' => __( 'Attach', 'attachments' ),
|
644 |
+
|
645 |
+
// fields for this instance (array)
|
646 |
+
'fields' => array(
|
647 |
+
array(
|
648 |
+
'name' => 'title', // unique field name
|
649 |
+
'type' => 'text', // registered field type
|
650 |
+
'label' => __( 'Title', 'attachments' ), // label to display
|
651 |
+
),
|
652 |
+
array(
|
653 |
+
'name' => 'caption', // unique field name
|
654 |
+
'type' => 'text', // registered field type
|
655 |
+
'label' => __( 'Caption', 'attachments' ), // label to display
|
656 |
+
),
|
657 |
+
),
|
658 |
+
|
659 |
+
);
|
660 |
+
|
661 |
+
$params = array_merge( $defaults, $params );
|
662 |
+
|
663 |
+
// sanitize
|
664 |
+
if( !is_array( $params['post_type'] ) )
|
665 |
+
$params['post_type'] = array( $params['post_type'] ); // we always want an array
|
666 |
+
|
667 |
+
if( !is_array( $params['filetype'] ) )
|
668 |
+
$params['filetype'] = array( $params['filetype'] ); // we always want an array
|
669 |
+
|
670 |
+
$params['label'] = esc_html( $params['label'] );
|
671 |
+
$params['limit'] = intval( $params['limit'] );
|
672 |
+
$params['note'] = esc_sql( $params['note'] );
|
673 |
+
$params['button_text'] = esc_attr( $params['button_text'] );
|
674 |
+
$params['modal_text'] = esc_attr( $params['modal_text'] );
|
675 |
+
|
676 |
+
// make sure we've got valid filetypes
|
677 |
+
if( is_array( $params['filetype'] ) )
|
678 |
+
{
|
679 |
+
foreach( $params['filetype'] as $key => $filetype )
|
680 |
+
{
|
681 |
+
if( !in_array( $filetype, $this->valid_filetypes ) )
|
682 |
+
{
|
683 |
+
unset( $params['filetype'][$key] );
|
684 |
+
}
|
685 |
+
}
|
686 |
+
}
|
687 |
+
|
688 |
+
// make sure the instance name is proper
|
689 |
+
$instance = str_replace( '-', '_', sanitize_title( $name ) );
|
690 |
+
|
691 |
+
// register the fields
|
692 |
+
if( isset( $params['fields'] ) && is_array( $params['fields'] ) && count( $params['fields'] ) )
|
693 |
+
{
|
694 |
+
foreach( $params['fields'] as $field )
|
695 |
+
{
|
696 |
+
// register the field
|
697 |
+
$this->register_field( $field );
|
698 |
+
}
|
699 |
+
}
|
700 |
+
|
701 |
+
// set the instance
|
702 |
+
$this->instances[$instance] = $params;
|
703 |
+
|
704 |
+
// set the Attachments for this instance
|
705 |
+
$this->instances[$instance]['attachments'] = $this->get_attachments( $instance );
|
706 |
+
|
707 |
+
}
|
708 |
+
|
709 |
+
|
710 |
+
|
711 |
+
/**
|
712 |
+
* Gets the applicable Attachments instances for the current post type
|
713 |
+
*
|
714 |
+
* @since 3.0
|
715 |
+
*/
|
716 |
+
function get_instances_for_post_type( $post_type = null )
|
717 |
+
{
|
718 |
+
$post_type = ( !is_null( $post_type ) && post_type_exists( $post_type ) ) ? $post_type : $this->get_post_type();
|
719 |
+
|
720 |
+
$instances = array();
|
721 |
+
|
722 |
+
if( !empty( $this->instances ) )
|
723 |
+
{
|
724 |
+
foreach( $this->instances as $name => $params )
|
725 |
+
{
|
726 |
+
if( in_array( $post_type, $params['post_type'] ) )
|
727 |
+
{
|
728 |
+
$instances[] = $name;
|
729 |
+
}
|
730 |
+
}
|
731 |
+
}
|
732 |
+
|
733 |
+
return $instances;
|
734 |
+
}
|
735 |
+
|
736 |
+
|
737 |
+
|
738 |
+
/**
|
739 |
+
* Our own implementation of WordPress' get_post_type() as it's not
|
740 |
+
* functional when we need it
|
741 |
+
*
|
742 |
+
* @since 3.0
|
743 |
+
*/
|
744 |
+
function get_post_type()
|
745 |
+
{
|
746 |
+
global $post;
|
747 |
+
|
748 |
+
// TODO: Retrieving the post_type at this point is ugly to say the least. This needs major cleanup.
|
749 |
+
if( empty( $post->ID ) && isset( $_GET['post_type'] ) )
|
750 |
+
{
|
751 |
+
$post_type = str_replace( '-', '_', sanitize_title( $_GET['post_type'] ) ); // TODO: Better sanitization
|
752 |
+
}
|
753 |
+
elseif( !empty( $post->ID ) )
|
754 |
+
{
|
755 |
+
$post_type = get_post_type( $post->ID );
|
756 |
+
}
|
757 |
+
elseif( isset( $_GET['post'] ) )
|
758 |
+
{
|
759 |
+
$post_type = get_post_type( intval( $_GET['post'] ) );
|
760 |
+
}
|
761 |
+
else
|
762 |
+
{
|
763 |
+
$post_type = 'post';
|
764 |
+
}
|
765 |
+
|
766 |
+
return $post_type;
|
767 |
+
}
|
768 |
+
|
769 |
+
|
770 |
+
|
771 |
+
/**
|
772 |
+
* Sets the applicable Attachments instances for the current post type
|
773 |
+
*
|
774 |
+
* @since 3.0
|
775 |
+
*/
|
776 |
+
function set_instances_for_current_post_type()
|
777 |
+
{
|
778 |
+
// store the applicable instances for this post type
|
779 |
+
$this->instances_for_post_type = $this->get_instances_for_post_type( $this->get_post_type() );
|
780 |
+
}
|
781 |
+
|
782 |
+
|
783 |
+
|
784 |
+
/**
|
785 |
+
* Outputs HTML for a single Attachment within an instance
|
786 |
+
*
|
787 |
+
* @since 3.0
|
788 |
+
*/
|
789 |
+
function create_attachment_field( $instance, $field, $attachment = null )
|
790 |
+
{
|
791 |
+
|
792 |
+
// the $field at this point is just the user-declared array
|
793 |
+
// we need to make it a field object
|
794 |
+
$type = $field['type'];
|
795 |
+
|
796 |
+
if( isset( $this->fields[$type] ) )
|
797 |
+
{
|
798 |
+
$name = sanitize_title( $field['name'] );
|
799 |
+
$label = esc_html( $field['label'] );
|
800 |
+
|
801 |
+
$value = ( isset( $attachment->fields->$name ) ) ? $attachment->fields->$name : null;
|
802 |
+
|
803 |
+
$field = new $this->fields[$type]( $name, $label, $value );
|
804 |
+
$field->Pvalue = $field->format_value_for_input( $field->value );
|
805 |
+
|
806 |
+
// does this field already have a unique ID?
|
807 |
+
$uid = ( isset( $attachment->uid ) ) ? $attachment->uid : null;
|
808 |
+
|
809 |
+
// TODO: make sure we've got a registered instance
|
810 |
+
$field->set_field_instance( $instance, $field );
|
811 |
+
$field->set_field_identifiers( $field, $uid );
|
812 |
+
$field->set_field_type( $type );
|
813 |
+
|
814 |
+
?>
|
815 |
+
<div class="attachments-attachment-field attachments-attachment-field-<?php echo $instance; ?> attachments-attachment-field-<?php echo $field->type; ?> attachment-field-<?php echo $field->name; ?>">
|
816 |
+
<div class="attachment-label attachment-label-<?php echo $instance; ?>">
|
817 |
+
<label for="<?php echo $field->field_id; ?>"><?php echo $field->label; ?></label>
|
818 |
+
</div>
|
819 |
+
<div class="attachment-field attachment-field-<?php echo $instance; ?>">
|
820 |
+
<?php echo $this->create_field( $instance, $field ); ?>
|
821 |
+
</div>
|
822 |
+
</div>
|
823 |
+
<?php
|
824 |
+
}
|
825 |
+
else
|
826 |
+
{
|
827 |
+
$field = false;
|
828 |
+
}
|
829 |
+
|
830 |
+
return $field;
|
831 |
+
}
|
832 |
+
|
833 |
+
|
834 |
+
|
835 |
+
/**
|
836 |
+
* Outputs HTML for submitted field
|
837 |
+
*
|
838 |
+
* @since 3.0
|
839 |
+
*/
|
840 |
+
function create_field( $instance, $field )
|
841 |
+
{
|
842 |
+
$field = (object) $field;
|
843 |
+
|
844 |
+
// with all of our attributes properly set, we can output
|
845 |
+
$field->html( $field );
|
846 |
+
}
|
847 |
+
|
848 |
+
|
849 |
+
|
850 |
+
/**
|
851 |
+
* Outputs all the necessary markup for an Attachment
|
852 |
+
*
|
853 |
+
* @since 3.0
|
854 |
+
*/
|
855 |
+
function create_attachment( $instance, $attachment = null )
|
856 |
+
{
|
857 |
+
?>
|
858 |
+
<div class="attachments-attachment attachments-attachment-<?php echo $instance; ?>">
|
859 |
+
<?php $array_flag = ( isset( $attachment->uid ) ) ? $attachment->uid : '{{ attachments.attachment_uid }}'; ?>
|
860 |
+
|
861 |
+
<input type="hidden" name="attachments[<?php echo $instance; ?>][<?php echo $array_flag; ?>][id]" value="<?php echo isset( $attachment->id ) ? $attachment->id : '{{ attachments.id }}' ; ?>" />
|
862 |
+
|
863 |
+
<?php
|
864 |
+
// since attributes can change over time (image gets replaced, cropped, etc.) we'll pull that info
|
865 |
+
if( isset( $attachment->id ) )
|
866 |
+
{
|
867 |
+
// we'll just use the full size since that's what Media in 3.5 uses
|
868 |
+
$attachment_meta = wp_get_attachment_metadata( $attachment->id );
|
869 |
+
|
870 |
+
// only images return the 'file' key
|
871 |
+
if( !isset( $attachment_meta['file'] ))
|
872 |
+
$attachment_meta['file'] = get_attached_file( $attachment->id );
|
873 |
+
|
874 |
+
$attachment->width = isset( $attachment_meta['width'] ) ? $attachment_meta['width'] : null;
|
875 |
+
$attachment->height = isset( $attachment_meta['height'] ) ? $attachment_meta['height'] : null;
|
876 |
+
$attachment->filename = end( explode( "/", $attachment_meta['file'] ) );
|
877 |
+
|
878 |
+
$attachment_mime = explode( '/', get_post_mime_type( $attachment->id ) );
|
879 |
+
$attachment->type = isset( $attachment_mime[0] ) ? $attachment_mime[0] : null;
|
880 |
+
$attachment->subtype = isset( $attachment_mime[1] ) ? $attachment_mime[1] : null;
|
881 |
+
}
|
882 |
+
?>
|
883 |
+
|
884 |
+
<div class="attachment-meta media-sidebar">
|
885 |
+
<?php
|
886 |
+
$thumbnail = isset( $attachment->id ) ? wp_get_attachment_image_src( $attachment->id, 'thumbnail', true ) : false;
|
887 |
+
|
888 |
+
$image = $thumbnail ? $thumbnail[0] : '{{ attachments.attachment_thumb }}';
|
889 |
+
?>
|
890 |
+
<div class="attachment-thumbnail">
|
891 |
+
<img src="<?php echo $image; ?>" alt="Thumbnail" />
|
892 |
+
</div>
|
893 |
+
<div class="attachment-details attachment-info details">
|
894 |
+
<div class="filename"><?php echo isset( $attachment->filename ) ? $attachment->filename : '{{ attachments.filename }}' ; ?></div>
|
895 |
+
<?php if( ( isset( $attachment->id ) && isset( $attachment->width ) ) || !isset( $attachment->id ) ) : ?>
|
896 |
+
<div class="dimensions"><?php echo isset( $attachment->width ) ? $attachment->width : '{{ attachments.width }}' ; ?> × <?php echo isset( $attachment->height ) ? $attachment->height : '{{ attachments.height }}' ; ?></div>
|
897 |
+
<?php endif; ?>
|
898 |
+
<div class="delete-attachment"><a href="#"><?php _e( 'Delete', 'attachments' ); ?></a></div>
|
899 |
+
</div>
|
900 |
+
</div>
|
901 |
+
|
902 |
+
<div class="attachments-handle"><img src="<?php echo trailingslashit( $this->url ) . 'images/handle.gif'; ?>" alt="Handle" width="20" height="20" /></div>
|
903 |
+
|
904 |
+
<div class="attachments-fields">
|
905 |
+
<?php
|
906 |
+
foreach( $this->instances[$instance]['fields'] as $field )
|
907 |
+
$field_ref = $this->create_attachment_field( $instance, $field, $attachment );
|
908 |
+
?>
|
909 |
+
</div>
|
910 |
+
|
911 |
+
</div>
|
912 |
+
<?php
|
913 |
+
}
|
914 |
+
|
915 |
+
|
916 |
+
|
917 |
+
/**
|
918 |
+
* Outputs all necessary Backbone templates
|
919 |
+
* Each Backbone template includes each field present in an instance
|
920 |
+
*
|
921 |
+
* @since 3.0
|
922 |
+
*/
|
923 |
+
function admin_footer()
|
924 |
+
{
|
925 |
+
if( !empty( $this->instances_for_post_type ) )
|
926 |
+
{ ?>
|
927 |
+
<script type="text/javascript">
|
928 |
+
var ATTACHMENTS_VIEWS = {};
|
929 |
+
</script>
|
930 |
+
<?php
|
931 |
+
foreach( $this->instances_for_post_type as $instance ) : ?>
|
932 |
+
<script type="text/template" id="tmpl-attachments-<?php echo $instance; ?>">
|
933 |
+
<?php $this->create_attachment( $instance ); ?>
|
934 |
+
</script>
|
935 |
+
<?php endforeach;
|
936 |
+
}
|
937 |
+
}
|
938 |
+
|
939 |
+
|
940 |
+
|
941 |
+
/**
|
942 |
+
* Saves our Attachments metadata when the post is saved
|
943 |
+
*
|
944 |
+
* @since 3.0
|
945 |
+
*/
|
946 |
+
function save( $post_id )
|
947 |
+
{
|
948 |
+
// is the user logged in?
|
949 |
+
if( !is_user_logged_in() )
|
950 |
+
return $post_id;
|
951 |
+
|
952 |
+
// is the nonce set?
|
953 |
+
if( !isset( $_POST['attachments_nonce'] ) )
|
954 |
+
return $post_id;
|
955 |
+
|
956 |
+
// is the nonce valid?
|
957 |
+
if( !wp_verify_nonce( $_POST['attachments_nonce'], 'attachments_save' ) )
|
958 |
+
return $post_id;
|
959 |
+
|
960 |
+
// can this user edit this post?
|
961 |
+
if( !current_user_can( 'edit_post', $post_id ) )
|
962 |
+
return $post_id;
|
963 |
+
|
964 |
+
// passed authentication, proceed with save
|
965 |
+
|
966 |
+
// if the user deleted all Attachments we won't have our key
|
967 |
+
$attachments_meta = isset( $_POST['attachments'] ) ? $_POST['attachments'] : array();
|
968 |
+
|
969 |
+
// final data store
|
970 |
+
$attachments = array();
|
971 |
+
|
972 |
+
// loop through each submitted instance
|
973 |
+
foreach( $attachments_meta as $instance => $instance_attachments )
|
974 |
+
{
|
975 |
+
// loop through each Attachment of this instance
|
976 |
+
foreach( $instance_attachments as $key => $attachment )
|
977 |
+
{
|
978 |
+
// since we're using JSON for storage in the database, we need
|
979 |
+
// to make sure that characters are encoded that would otherwise
|
980 |
+
// break the JSON
|
981 |
+
if( isset( $attachment['fields'] ) && is_array( $attachment['fields'] ) )
|
982 |
+
{
|
983 |
+
|
984 |
+
foreach( $attachment['fields'] as $key => $field_value )
|
985 |
+
{
|
986 |
+
// slashes were already added so we're going to strip them and encode ourselves
|
987 |
+
$attachment['fields'][$key] = htmlentities( stripslashes( $field_value ), ENT_QUOTES, 'UTF-8' );
|
988 |
+
}
|
989 |
+
}
|
990 |
+
|
991 |
+
$attachments[$instance][] = $attachment;
|
992 |
+
}
|
993 |
+
}
|
994 |
+
|
995 |
+
// we're going to store JSON
|
996 |
+
$attachments = json_encode( $attachments );
|
997 |
+
|
998 |
+
// we're going to wipe out any existing Attachments meta (because we'll put it back)
|
999 |
+
update_post_meta( $post_id, $this->meta_key, $attachments );
|
1000 |
+
}
|
1001 |
+
|
1002 |
+
|
1003 |
+
|
1004 |
+
/**
|
1005 |
+
* Retrieves all Attachments for the submitted instance and post ID
|
1006 |
+
*
|
1007 |
+
* @since 3.0
|
1008 |
+
*/
|
1009 |
+
function get_attachments( $instance = '', $post_id = null )
|
1010 |
+
{
|
1011 |
+
global $post;
|
1012 |
+
|
1013 |
+
// if a post id was passed, we'll use it
|
1014 |
+
if( !is_null( $post_id ) )
|
1015 |
+
{
|
1016 |
+
$post_id = intval( $post_id );
|
1017 |
+
}
|
1018 |
+
elseif( is_null( $post_id ) && is_object( $post ) && isset( $post->ID ) )
|
1019 |
+
{
|
1020 |
+
$post_id = $post->ID;
|
1021 |
+
}
|
1022 |
+
elseif( isset( $_GET['post'] ) )
|
1023 |
+
{
|
1024 |
+
$post_id = intval( $_GET['post'] );
|
1025 |
+
}
|
1026 |
+
else
|
1027 |
+
{
|
1028 |
+
// no post ID, nothing to do...
|
1029 |
+
return;
|
1030 |
+
}
|
1031 |
+
|
1032 |
+
// grab our JSON and decode it
|
1033 |
+
$attachments_json = get_post_meta( $post_id, $this->meta_key, true );
|
1034 |
+
$attachments_raw = is_string( $attachments_json ) ? json_decode( $attachments_json ) : false;
|
1035 |
+
|
1036 |
+
// we need to decode the fields (that were encoded during save) and run them through
|
1037 |
+
// their format_value_for_input as defined in it's class
|
1038 |
+
if( isset( $attachments_raw->$instance ) )
|
1039 |
+
{
|
1040 |
+
foreach( $attachments_raw->$instance as $attachment )
|
1041 |
+
{
|
1042 |
+
if( is_object( $attachment->fields ) )
|
1043 |
+
{
|
1044 |
+
foreach( $attachment->fields as $key => $value )
|
1045 |
+
{
|
1046 |
+
// loop through the instance fields to get the type
|
1047 |
+
if( isset( $this->instances[$instance]['fields'] ) )
|
1048 |
+
{
|
1049 |
+
$type = '';
|
1050 |
+
foreach( $this->instances[$instance]['fields'] as $field )
|
1051 |
+
{
|
1052 |
+
if( isset( $field['name'] ) && $field['name'] == $key )
|
1053 |
+
{
|
1054 |
+
$type = isset( $field['type'] ) ? $field['type'] : false;
|
1055 |
+
break;
|
1056 |
+
}
|
1057 |
+
}
|
1058 |
+
|
1059 |
+
if( isset( $this->fields[$type] ) )
|
1060 |
+
{
|
1061 |
+
// we need to decode the html entities that were encoded for the save
|
1062 |
+
$attachment->fields->$key = html_entity_decode( $attachment->fields->$key, ENT_QUOTES, 'UTF-8' );
|
1063 |
+
}
|
1064 |
+
else
|
1065 |
+
{
|
1066 |
+
// the type doesn't exist
|
1067 |
+
$attachment->fields->$key = false;
|
1068 |
+
}
|
1069 |
+
}
|
1070 |
+
}
|
1071 |
+
}
|
1072 |
+
$attachments[] = $attachment;
|
1073 |
+
}
|
1074 |
+
}
|
1075 |
+
else
|
1076 |
+
{
|
1077 |
+
$attachments = false;
|
1078 |
+
}
|
1079 |
+
|
1080 |
+
return $attachments;
|
1081 |
+
}
|
1082 |
+
|
1083 |
+
|
1084 |
+
|
1085 |
+
/**
|
1086 |
+
* Determines whether or not there is 'active' legacy data the user may not know about
|
1087 |
+
*
|
1088 |
+
* @since 3.0
|
1089 |
+
*/
|
1090 |
+
function has_outstanding_legacy_data()
|
1091 |
+
{
|
1092 |
+
if(
|
1093 |
+
// migration has not taken place and we have legacy data
|
1094 |
+
( false == get_option( 'attachments_migrated' ) && !empty( $this->legacy ) )
|
1095 |
+
|
1096 |
+
&&
|
1097 |
+
|
1098 |
+
// we're not intentionally ignoring the message
|
1099 |
+
( false == get_option( 'attachments_ignore_migration' ) )
|
1100 |
+
)
|
1101 |
+
{
|
1102 |
+
return true;
|
1103 |
+
}
|
1104 |
+
else
|
1105 |
+
{
|
1106 |
+
return false;
|
1107 |
+
}
|
1108 |
+
}
|
1109 |
+
|
1110 |
+
|
1111 |
+
|
1112 |
+
/**
|
1113 |
+
* Outputs a WordPress message to notify user of legacy data
|
1114 |
+
*
|
1115 |
+
* @since 3.0
|
1116 |
+
*/
|
1117 |
+
function admin_notice()
|
1118 |
+
{
|
1119 |
+
|
1120 |
+
if( $this->has_outstanding_legacy_data() && ( isset( $_GET['page'] ) && $_GET['page'] !== 'attachments' || !isset( $_GET['page'] ) ) ) : ?>
|
1121 |
+
<div class="message updated" id="message">
|
1122 |
+
<p><?php _e( '<strong>Attachments has detected legacy Attachments data.</strong> A lot has changed since Attachments 1.x.' ,'attachments' ); ?> <a href="options-general.php?page=attachments&overview=1"><?php _e( 'Find out more', 'attachments' ); ?>.</a></p>
|
1123 |
+
</div>
|
1124 |
+
<?php endif;
|
1125 |
+
}
|
1126 |
+
|
1127 |
+
|
1128 |
+
|
1129 |
+
/**
|
1130 |
+
* Implements our WordPress pointer if necessary
|
1131 |
+
*
|
1132 |
+
* @since 3.0
|
1133 |
+
*/
|
1134 |
+
function admin_pointer( $hook_suffix )
|
1135 |
+
{
|
1136 |
+
|
1137 |
+
// Assume pointer shouldn't be shown
|
1138 |
+
$enqueue_pointer_script_style = false;
|
1139 |
+
|
1140 |
+
// Get array list of dismissed pointers for current user and convert it to array
|
1141 |
+
$dismissed_pointers = explode( ',', get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
|
1142 |
+
|
1143 |
+
// Check if our pointer is not among dismissed ones
|
1144 |
+
if( $this->legacy && !in_array( 'attachments_legacy', $dismissed_pointers ) ) {
|
1145 |
+
$enqueue_pointer_script_style = true;
|
1146 |
+
|
1147 |
+
// Add footer scripts using callback function
|
1148 |
+
add_action( 'admin_print_footer_scripts', array( $this, 'pointer_legacy' ) );
|
1149 |
+
}
|
1150 |
+
|
1151 |
+
// Enqueue pointer CSS and JS files, if needed
|
1152 |
+
if( $enqueue_pointer_script_style ) {
|
1153 |
+
wp_enqueue_style( 'wp-pointer' );
|
1154 |
+
wp_enqueue_script( 'wp-pointer' );
|
1155 |
+
}
|
1156 |
+
}
|
1157 |
+
|
1158 |
+
|
1159 |
+
|
1160 |
+
/**
|
1161 |
+
* Pointer that calls attention to legacy data
|
1162 |
+
*
|
1163 |
+
* @since 3.0
|
1164 |
+
*/
|
1165 |
+
function pointer_legacy()
|
1166 |
+
{
|
1167 |
+
$pointer_content = "<h3>". __( esc_html( 'Attachments 3.0 brings big changes!' ), 'attachments' ) ."</h3>";
|
1168 |
+
$pointer_content .= "<p>". __( esc_html( 'It is very important that you take a few minutes to see what has been updated. The changes will affect your themes/plugins.' ), 'attachments' ) ."</p>";
|
1169 |
+
?>
|
1170 |
+
|
1171 |
+
<script type="text/javascript">
|
1172 |
+
jQuery(document).ready( function($) {
|
1173 |
+
$('#message a').pointer({
|
1174 |
+
content:'<?php echo $pointer_content; ?>',
|
1175 |
+
position:{
|
1176 |
+
edge:'top',
|
1177 |
+
align:'center'
|
1178 |
+
},
|
1179 |
+
pointerWidth:350,
|
1180 |
+
close:function() {
|
1181 |
+
$.post( ajaxurl, {
|
1182 |
+
pointer: 'attachments_legacy',
|
1183 |
+
action: 'dismiss-wp-pointer'
|
1184 |
+
});
|
1185 |
+
}
|
1186 |
+
}).pointer('open');
|
1187 |
+
});
|
1188 |
+
</script>
|
1189 |
+
<?php
|
1190 |
+
}
|
1191 |
+
|
1192 |
+
|
1193 |
+
|
1194 |
+
/**
|
1195 |
+
* Callback to implement our Settings page
|
1196 |
+
*
|
1197 |
+
* @since 3.0
|
1198 |
+
*/
|
1199 |
+
function admin_page()
|
1200 |
+
{
|
1201 |
+
add_options_page( 'Settings', __( 'Attachments', 'attachments' ), 'manage_options', 'attachments', array( $this, 'options_page' ) );
|
1202 |
+
}
|
1203 |
+
|
1204 |
+
|
1205 |
+
|
1206 |
+
/**
|
1207 |
+
* Callback to output our Settings page markup
|
1208 |
+
*
|
1209 |
+
* @since 3.0
|
1210 |
+
*/
|
1211 |
+
function options_page()
|
1212 |
+
{
|
1213 |
+
include_once( ATTACHMENTS_DIR . '/views/options.php' );
|
1214 |
+
}
|
1215 |
+
|
1216 |
+
}
|
1217 |
+
|
1218 |
+
endif; // class_exists check
|
1219 |
+
|
1220 |
+
new Attachments();
|
classes/class.field.php
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Attachments Field Base Class
|
5 |
+
*
|
6 |
+
* @package Attachments
|
7 |
+
* @subpackage Main
|
8 |
+
*/
|
9 |
+
|
10 |
+
// Declare our class
|
11 |
+
if ( !class_exists( 'Attachments_Field' ) ) :
|
12 |
+
|
13 |
+
interface Attachments_Field_Template
|
14 |
+
{
|
15 |
+
public function html( $field );
|
16 |
+
public function format_value_for_input( $value, $field = null );
|
17 |
+
public function input_head();
|
18 |
+
}
|
19 |
+
|
20 |
+
class Attachments_Field implements Attachments_Field_Template
|
21 |
+
{
|
22 |
+
public $instance; // the instance this field is used within
|
23 |
+
public $name; // the user-defined field name
|
24 |
+
public $field_name; // the name attribute to be used
|
25 |
+
public $field_id; // the id attribute to be used
|
26 |
+
public $label; // the field label
|
27 |
+
public $type; // field type as it was registered
|
28 |
+
public $uid; // unique id for field
|
29 |
+
public $value; // the value for the field
|
30 |
+
|
31 |
+
function __construct( $name = 'name', $label = 'Name', $value = null )
|
32 |
+
{
|
33 |
+
$this->name = sanitize_title( $name );
|
34 |
+
$this->label = __( esc_attr( $label) );
|
35 |
+
$this->value = $value;
|
36 |
+
}
|
37 |
+
|
38 |
+
function set_field_instance( $instance, $field )
|
39 |
+
{
|
40 |
+
$field->instance = $instance;
|
41 |
+
}
|
42 |
+
|
43 |
+
function set_field_identifiers( $field, $uid = null )
|
44 |
+
{
|
45 |
+
// we MUST have an instance
|
46 |
+
if( empty( $field->instance ) )
|
47 |
+
return false;
|
48 |
+
|
49 |
+
// if we're pulling an existing Attachment (field has a value) we're going to use
|
50 |
+
// a PHP uniqid to set up our array flags but if we're setting up our Underscore
|
51 |
+
// template we need to use a variable flag to be processed later
|
52 |
+
$this->uid = !is_null( $uid ) ? $uid : '{{ attachments.attachment_uid }}';
|
53 |
+
|
54 |
+
// set the name
|
55 |
+
$field->field_name = "attachments[$field->instance][$this->uid][fields][$field->name]";
|
56 |
+
|
57 |
+
// set the id
|
58 |
+
$field->field_id = $this->field_name . $this->uid;
|
59 |
+
}
|
60 |
+
|
61 |
+
function set_field_type( $field_type )
|
62 |
+
{
|
63 |
+
$this->type = $field_type;
|
64 |
+
}
|
65 |
+
|
66 |
+
public function html( $field )
|
67 |
+
{
|
68 |
+
?>
|
69 |
+
<input type="text" name="<?php esc_attr_e( $field->field_name ); ?>" id="<?php esc_attr_e( $field->field_id ); ?>" class="attachments attachments-field attachments-field-<?php esc_attr_e( $field->field_name ); ?> attachments-field-<?php esc_attr_e( $field->field_id ); ?>" value="<?php esc_attr_e( $field->value ); ?>" />
|
70 |
+
<?php
|
71 |
+
}
|
72 |
+
|
73 |
+
public function format_value_for_input( $value, $field = null )
|
74 |
+
{
|
75 |
+
return $value;
|
76 |
+
}
|
77 |
+
|
78 |
+
public function input_head()
|
79 |
+
{
|
80 |
+
return;
|
81 |
+
}
|
82 |
+
|
83 |
+
}
|
84 |
+
|
85 |
+
endif; // class_exists check
|
classes/fields/class.field.text.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Attachments text field
|
5 |
+
*
|
6 |
+
* @package Attachments
|
7 |
+
* @subpackage Main
|
8 |
+
*/
|
9 |
+
|
10 |
+
class Attachments_Field_Text extends Attachments_Field implements Attachments_Field_Template
|
11 |
+
{
|
12 |
+
|
13 |
+
function __construct( $name = 'name', $label = 'Name', $value = null )
|
14 |
+
{
|
15 |
+
parent::__construct( $name, $label, $value );
|
16 |
+
}
|
17 |
+
|
18 |
+
function html( $field )
|
19 |
+
{
|
20 |
+
?>
|
21 |
+
<input type="text" name="<?php esc_attr_e( $field->field_name ); ?>" id="<?php esc_attr_e( $field->field_id ); ?>" class="attachments attachments-field attachments-field-<?php esc_attr_e( $field->field_name ); ?> attachments-field-<?php esc_attr_e( $field->field_id ); ?>" value="<?php esc_attr_e( $field->value ); ?>" />
|
22 |
+
<?php
|
23 |
+
}
|
24 |
+
|
25 |
+
function format_value_for_input( $value, $field = null )
|
26 |
+
{
|
27 |
+
return htmlspecialchars( $value, ENT_QUOTES );
|
28 |
+
}
|
29 |
+
|
30 |
+
public function input_head()
|
31 |
+
{
|
32 |
+
return;
|
33 |
+
}
|
34 |
+
|
35 |
+
}
|
classes/fields/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php
|
classes/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php
|
css/attachments.css
CHANGED
@@ -1,73 +1,166 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
/*
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
a.attachments-invoke {
|
2 |
+
margin-top:5px;
|
3 |
+
margin-bottom:4px;
|
4 |
+
}
|
5 |
+
|
6 |
+
.attachments-attachment {
|
7 |
+
position:relative;
|
8 |
+
overflow:hidden;
|
9 |
+
zoom:1;
|
10 |
+
padding:5px 0 25px;
|
11 |
+
border-bottom:1px solid #e7e7e7;
|
12 |
+
}
|
13 |
+
|
14 |
+
.attachments-attachment:first-of-type {
|
15 |
+
padding-top:0;
|
16 |
+
}
|
17 |
+
|
18 |
+
.attachments-attachment:last-of-type {
|
19 |
+
border-bottom:0;
|
20 |
+
margin-bottom:30px;
|
21 |
+
padding-bottom:0;
|
22 |
+
}
|
23 |
+
|
24 |
+
.attachments-note {
|
25 |
+
padding-bottom:8px;
|
26 |
+
}
|
27 |
+
|
28 |
+
.attachments-note:not(:empty) + .attachments-container > .attachments-attachment:first-of-type {
|
29 |
+
margin-top:-20px;
|
30 |
+
}
|
31 |
+
|
32 |
+
.attachments-container {
|
33 |
+
padding-bottom:34px;
|
34 |
+
}
|
35 |
+
|
36 |
+
.attachments-invoke-wrapper {
|
37 |
+
position:absolute;
|
38 |
+
bottom:0;
|
39 |
+
left:0;
|
40 |
+
width:100%;
|
41 |
+
height:36px;
|
42 |
+
padding-top:12px;
|
43 |
+
background:#fcfcfc;
|
44 |
+
margin-bottom:-8px;
|
45 |
+
border-bottom-left-radius:3px;
|
46 |
+
border-bottom-right-radius:3px;
|
47 |
+
text-align:center;
|
48 |
+
border-top:1px solid #dfdfdf;
|
49 |
+
}
|
50 |
+
|
51 |
+
.attachments-container .ui-sortable-helper {
|
52 |
+
background:#F9F9F9;
|
53 |
+
}
|
54 |
+
|
55 |
+
.attachments-attachment-highlight {
|
56 |
+
min-height:125px;
|
57 |
+
background:#f1f1f1;
|
58 |
+
border:1px solid #cecece;
|
59 |
+
border-radius:2px;
|
60 |
+
}
|
61 |
+
|
62 |
+
.attachments-attachment .attachment-meta {
|
63 |
+
/* Reset some WP defaults */
|
64 |
+
bottom:auto;
|
65 |
+
border:0;
|
66 |
+
|
67 |
+
/* Our styles */
|
68 |
+
position:absolute;
|
69 |
+
right:0;
|
70 |
+
top:0;
|
71 |
+
margin-top:36px;
|
72 |
+
width:225px;
|
73 |
+
overflow:hidden;
|
74 |
+
zoom:1;
|
75 |
+
padding:5px;
|
76 |
+
background:#fdfdfd;
|
77 |
+
border:1px solid #DFDFDF;
|
78 |
+
border:1px solid rgba(223,223,223,0.8);
|
79 |
+
border-radius:2px;
|
80 |
+
}
|
81 |
+
|
82 |
+
.attachments-attachment:first-of-type .attachment-meta {
|
83 |
+
margin-top:32px;
|
84 |
+
}
|
85 |
+
|
86 |
+
.attachments-attachment .attachment-meta .attachment-info {
|
87 |
+
/* Reset some WP defaults */
|
88 |
+
min-height:1px;
|
89 |
+
margin-bottom:0;
|
90 |
+
border-bottom:0;
|
91 |
+
box-shadow:none;
|
92 |
+
padding-bottom:0;
|
93 |
+
}
|
94 |
+
|
95 |
+
.attachments-attachment .attachment-meta .attachment-details {
|
96 |
+
width:135px;
|
97 |
+
float:right;
|
98 |
+
margin:0;
|
99 |
+
padding:0;
|
100 |
+
}
|
101 |
+
|
102 |
+
.attachments-attachment .attachment-meta .attachment-info .filename {
|
103 |
+
white-space:nowrap;
|
104 |
+
width:100%;
|
105 |
+
overflow:hidden;
|
106 |
+
text-overflow:ellipsis;
|
107 |
+
}
|
108 |
+
|
109 |
+
.attachments-attachment .attachment-meta .attachment-thumbnail {
|
110 |
+
width:80px;
|
111 |
+
float:left;
|
112 |
+
}
|
113 |
+
|
114 |
+
.attachments-attachment .attachment-meta .attachment-thumbnail img {
|
115 |
+
display:block;
|
116 |
+
max-width:100%;
|
117 |
+
height:auto !important;
|
118 |
+
max-height:80px;
|
119 |
+
border-radius:2px;
|
120 |
+
margin:0 auto;
|
121 |
+
}
|
122 |
+
|
123 |
+
.attachments-attachment .attachment-meta .attachment-actions {
|
124 |
+
width:130px;
|
125 |
+
float:right;
|
126 |
+
}
|
127 |
+
|
128 |
+
.attachments-fields {
|
129 |
+
margin-right:250px;
|
130 |
+
margin-left:40px;
|
131 |
+
padding-top:10px;
|
132 |
+
}
|
133 |
+
|
134 |
+
.attachments-fields .attachments-attachment-field {
|
135 |
+
overflow:hidden;
|
136 |
+
zoom:1;
|
137 |
+
padding:8px 0;
|
138 |
+
}
|
139 |
+
|
140 |
+
.attachments-fields label {
|
141 |
+
display:block;
|
142 |
+
margin-bottom:3px;
|
143 |
+
}
|
144 |
+
|
145 |
+
|
146 |
+
/* Text field styling */
|
147 |
+
.attachments-attachment-field-text input {
|
148 |
+
display:block;
|
149 |
+
width:100%;
|
150 |
+
}
|
151 |
+
|
152 |
+
.attachments-handle {
|
153 |
+
position:absolute;
|
154 |
+
left:0;
|
155 |
+
top:20px;
|
156 |
+
opacity:0.5;
|
157 |
+
}
|
158 |
+
|
159 |
+
.attachments-attachment:first-of-type .attachments-handle {
|
160 |
+
top:17px;
|
161 |
+
}
|
162 |
+
|
163 |
+
.attachments-handle img {
|
164 |
+
display:block;
|
165 |
+
cursor:pointer;
|
166 |
+
}
|
css/index.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Do not modify the files in this folder.
|
5 |
+
*/
|
attachments.options.php → deprecated/attachments.options.php
RENAMED
File without changes
|
attachments.php → deprecated/attachments.php
RENAMED
@@ -1,11 +1,6 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
-
|
4 |
-
Plugin URI: http://mondaybynoon.com/wordpress-attachments/
|
5 |
-
Description: Attachments gives the ability to append any number of Media Library items to Pages, Posts, and Custom Post Types
|
6 |
-
Version: 1.6.2.1
|
7 |
-
Author: Jonathan Christopher
|
8 |
-
Author URI: http://mondaybynoon.com/
|
9 |
*/
|
10 |
|
11 |
/* Copyright 2009-2012 Jonathan Christopher (email : jonathan@irontoiron.com)
|
@@ -25,6 +20,9 @@
|
|
25 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
26 |
*/
|
27 |
|
|
|
|
|
|
|
28 |
|
29 |
// constant definition
|
30 |
if( !defined( 'IS_ADMIN' ) )
|
@@ -59,6 +57,9 @@ if( !version_compare( PHP_VERSION, '5.2', '>=' ) || !version_compare( $wp_versio
|
|
59 |
}
|
60 |
|
61 |
|
|
|
|
|
|
|
62 |
|
63 |
// =========
|
64 |
// = HOOKS =
|
@@ -265,34 +266,6 @@ function attachments_edit_post_types()
|
|
265 |
<?php }
|
266 |
|
267 |
|
268 |
-
/**
|
269 |
-
* Compares two array values with the same key "order"
|
270 |
-
*
|
271 |
-
* @param string $a First value
|
272 |
-
* @param string $b Second value
|
273 |
-
* @return int
|
274 |
-
* @author Jonathan Christopher
|
275 |
-
*/
|
276 |
-
function attachments_cmp($a, $b)
|
277 |
-
{
|
278 |
-
$a = intval( $a['order'] );
|
279 |
-
$b = intval( $b['order'] );
|
280 |
-
|
281 |
-
if( $a < $b )
|
282 |
-
{
|
283 |
-
return -1;
|
284 |
-
}
|
285 |
-
else if( $a > $b )
|
286 |
-
{
|
287 |
-
return 1;
|
288 |
-
}
|
289 |
-
else
|
290 |
-
{
|
291 |
-
return 0;
|
292 |
-
}
|
293 |
-
}
|
294 |
-
|
295 |
-
|
296 |
/**
|
297 |
* Creates the markup for the WordPress admin options page
|
298 |
*
|
@@ -382,7 +355,7 @@ function attachments_attachment_markup( $name = null, $title = null, $caption =
|
|
382 |
<li class="attachments-file">
|
383 |
<h2>
|
384 |
<a href="#" class="attachment-handle">
|
385 |
-
<span class="attachment-handle-icon"><img src="<?php echo WP_PLUGIN_URL; ?>/attachments/images/handle.gif" alt="Drag" /></span>
|
386 |
</a>
|
387 |
<span class="attachment-name"><?php echo empty( $name ) ? '{{name}}' : $name; ?></span>
|
388 |
<span class="attachment-delete"><a href="#"><?php _e("Delete", "attachments")?></a></span>
|
@@ -575,78 +548,4 @@ function attachments_save($post_id)
|
|
575 |
|
576 |
}
|
577 |
|
578 |
-
}
|
579 |
-
|
580 |
-
|
581 |
-
/**
|
582 |
-
* Returns a formatted filesize
|
583 |
-
*
|
584 |
-
* @param string $path Path to file on disk
|
585 |
-
* @return string $formatted formatted filesize
|
586 |
-
* @author Jonathan Christopher
|
587 |
-
*/
|
588 |
-
function attachments_get_filesize_formatted( $path = NULL )
|
589 |
-
{
|
590 |
-
$formatted = '0 bytes';
|
591 |
-
if( file_exists( $path ) )
|
592 |
-
{
|
593 |
-
$formatted = size_format( @filesize( $path ) );
|
594 |
-
}
|
595 |
-
return $formatted;
|
596 |
-
}
|
597 |
-
|
598 |
-
|
599 |
-
/**
|
600 |
-
* Retrieves all Attachments for provided Post or Page
|
601 |
-
*
|
602 |
-
* @param int $post_id (optional) ID of target Post or Page, otherwise pulls from global $post
|
603 |
-
* @return array $post_attachments
|
604 |
-
* @author Jonathan Christopher
|
605 |
-
* @author JR Tashjian
|
606 |
-
*/
|
607 |
-
|
608 |
-
function attachments_get_attachments( $post_id=null )
|
609 |
-
{
|
610 |
-
global $post;
|
611 |
-
|
612 |
-
if( $post_id==null )
|
613 |
-
{
|
614 |
-
$post_id = $post->ID;
|
615 |
-
}
|
616 |
-
|
617 |
-
// get all attachments
|
618 |
-
$existing_attachments = get_post_meta( $post_id, '_attachments', false );
|
619 |
-
|
620 |
-
// We can now proceed as normal, all legacy data should now be upgraded
|
621 |
-
|
622 |
-
$post_attachments = array();
|
623 |
-
|
624 |
-
if( is_array( $existing_attachments ) && count( $existing_attachments ) > 0 )
|
625 |
-
{
|
626 |
-
|
627 |
-
foreach ($existing_attachments as $attachment)
|
628 |
-
{
|
629 |
-
// decode and unserialize the data
|
630 |
-
$data = unserialize( base64_decode( $attachment ) );
|
631 |
-
|
632 |
-
array_push( $post_attachments, array(
|
633 |
-
'id' => stripslashes( $data['id'] ),
|
634 |
-
'name' => stripslashes( get_the_title( $data['id'] ) ),
|
635 |
-
'mime' => stripslashes( get_post_mime_type( $data['id'] ) ),
|
636 |
-
'title' => stripslashes( $data['title'] ),
|
637 |
-
'caption' => stripslashes( $data['caption'] ),
|
638 |
-
'filesize' => stripslashes( attachments_get_filesize_formatted( get_attached_file( $data['id'] ) ) ),
|
639 |
-
'location' => stripslashes( wp_get_attachment_url( $data['id'] ) ),
|
640 |
-
'order' => stripslashes( $data['order'] )
|
641 |
-
));
|
642 |
-
}
|
643 |
-
|
644 |
-
// sort attachments
|
645 |
-
if( count( $post_attachments ) > 1 )
|
646 |
-
{
|
647 |
-
usort( $post_attachments, "attachments_cmp" );
|
648 |
-
}
|
649 |
-
}
|
650 |
-
|
651 |
-
return $post_attachments;
|
652 |
}
|
1 |
<?php
|
2 |
/*
|
3 |
+
THIS IS A LEGACY VERSION OF ATTACHMENTS AND IS CONSIDERED DEPRECATED
|
|
|
|
|
|
|
|
|
|
|
4 |
*/
|
5 |
|
6 |
/* Copyright 2009-2012 Jonathan Christopher (email : jonathan@irontoiron.com)
|
20 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
21 |
*/
|
22 |
|
23 |
+
// Exit if accessed directly
|
24 |
+
if( !defined( 'ABSPATH' ) ) exit;
|
25 |
+
|
26 |
|
27 |
// constant definition
|
28 |
if( !defined( 'IS_ADMIN' ) )
|
57 |
}
|
58 |
|
59 |
|
60 |
+
// we moved all attachments_get_attachments() functions to an external file in version 3.0
|
61 |
+
include_once 'get-attachments.php';
|
62 |
+
|
63 |
|
64 |
// =========
|
65 |
// = HOOKS =
|
266 |
<?php }
|
267 |
|
268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
/**
|
270 |
* Creates the markup for the WordPress admin options page
|
271 |
*
|
355 |
<li class="attachments-file">
|
356 |
<h2>
|
357 |
<a href="#" class="attachment-handle">
|
358 |
+
<span class="attachment-handle-icon"><img src="<?php echo WP_PLUGIN_URL; ?>/attachments/deprecated/images/handle.gif" alt="Drag" /></span>
|
359 |
</a>
|
360 |
<span class="attachment-name"><?php echo empty( $name ) ? '{{name}}' : $name; ?></span>
|
361 |
<span class="attachment-delete"><a href="#"><?php _e("Delete", "attachments")?></a></span>
|
548 |
|
549 |
}
|
550 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
551 |
}
|
deprecated/css/attachments.css
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* ============ */
|
2 |
+
/* = META BOX = */
|
3 |
+
/* ============ */
|
4 |
+
|
5 |
+
#attachments-inner { padding-top:3px; }
|
6 |
+
ul#attachments-actions { overflow:hidden; zoom:1; padding-top:4px; }
|
7 |
+
ul#attachments-actions li { width:50%; float:left; }
|
8 |
+
li#attachments-add-new { float:right; text-align:right; }
|
9 |
+
|
10 |
+
#attachments-instructions { margin:0; padding:12px 0 !important; }
|
11 |
+
|
12 |
+
#attachments-file-list { padding:0; }
|
13 |
+
.attachments-file-section { padding:0 0 20px 0; }
|
14 |
+
p.attachments-actions { float:right; margin:6px 0 0 !important; }
|
15 |
+
|
16 |
+
#attachments-file-details .attachments img { display:block; }
|
17 |
+
#attachments-file-details .attachments a { display:block; border:3px solid #fff; float:left; }
|
18 |
+
#attachments-file-details .attachments a:hover { border:3px solid #ccc; }
|
19 |
+
|
20 |
+
#attachments-file-details .attachments a.attachments-selected { border:3px solid #eb3525; }
|
21 |
+
span.attachments-attached { background:#fff; color:#d54e21; padding-left:10px; font-style:italic; }
|
22 |
+
|
23 |
+
/* File listings, not images */
|
24 |
+
#attachments-file-details .attachments-alt li { width:290px; }
|
25 |
+
#attachments-file-details .attachments-alt span.attachments-thumbnail { display:block; width:70px; float:left; }
|
26 |
+
#attachments-file-details .attachments-alt h2.attachments-title-display { display:block; width:220px; float:left; text-decoration:none; font:20px Georgia,"Times New Roman","Bitstream Charter",Times,serif; font-style:italic; font-weight:normal; height:2.4em; overflow:hidden; }
|
27 |
+
|
28 |
+
#attachments-file-details .attachments-alt li a { display:block; border:0; text-decoration:none; }
|
29 |
+
#attachments-file-details .attachments-alt li a.attachments-selected { border:0; }
|
30 |
+
#attachments-file-details .attachments-alt li a span.attachments-thumbnail img { border:3px solid #fff; }
|
31 |
+
#attachments-file-details .attachments-alt li a.attachments-selected span.attachments-thumbnail img { border:3px solid #eb3525; }
|
32 |
+
|
33 |
+
|
34 |
+
/* ========================= */
|
35 |
+
/* = META BOX FILE LISTING = */
|
36 |
+
/* ========================= */
|
37 |
+
#attachments-list ul { padding:10px 0; }
|
38 |
+
#attachments-list li.attachments-file { overflow:hidden; zoom:1; }
|
39 |
+
.attachments-data { display:none; }
|
40 |
+
#poststuff li.attachments-file { height:115px; }
|
41 |
+
#poststuff li.attachments-file h2 { margin:0; overflow:hidden; zoom:1; }
|
42 |
+
#poststuff li.attachments-file h2 a { text-decoration:none; color:inherit; }
|
43 |
+
#poststuff li.attachments-file h2 span { display:block; float:left; }
|
44 |
+
#poststuff li.attachments-file h2 a span.attachment-handle-icon { padding:6px 0 0 0; cursor:move; }
|
45 |
+
#poststuff li.attachments-file h2 span.attachment-name { padding:0 10px; height:2em; overflow:hidden; width:60%; }
|
46 |
+
#poststuff li.attachments-file h2 span.attachment-delete { width:80px; text-align:center; padding:0.7em 0 0 0; float:right; margin-right:3px; }
|
47 |
+
#poststuff li.attachments-file h2 span.attachment-delete a { font:11px "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif; color:#21759b; text-decoration:underline; }
|
48 |
+
#poststuff li.attachments-file h2 span.attachment-delete a:hover { color:#d54e21; }
|
49 |
+
|
50 |
+
#attachments-list .attachments-file { overflow:hidden; zoom:1; }
|
51 |
+
#attachments-list .attachments-fields { width:80%; float:left; }
|
52 |
+
#attachments-list .attachment-thumbnail { width:80px; float:right; margin-right:3px; }
|
53 |
+
#attachments-list .attachments-thumbnail { width:80px; float:right; text-align:right; }
|
54 |
+
#attachments-list .attachments-thumbnail img { display:block; max-width:80px; margin:0 auto; }
|
55 |
+
|
56 |
+
.attachments-fields .textfield { overflow:hidden; zoom:1; padding-bottom:10px; }
|
57 |
+
.attachments-fields .textfield label { display:block; width:20%; float:left; padding-top:6px; }
|
58 |
+
.attachments-fields .textfield input { display:block; width:75%; float:left; }
|
59 |
+
|
60 |
+
|
61 |
+
/* =========== */
|
62 |
+
/* = OPTIONS = */
|
63 |
+
/* =========== */
|
64 |
+
.attachments_checkbox { overflow:hidden; zoom:1; padding:0 0 7px 0; }
|
65 |
+
.attachments_checkbox input { display:block; float:left; margin-top:2px; }
|
66 |
+
.attachments_checkbox label { display:block; float:left; padding:0 0 0 7px; }
|
67 |
+
.attachments_checkbox p.note { clear:both; font-style:italic; padding:4px 0 0 21px; max-width:550px; color:#888; }
|
68 |
+
|
69 |
+
#attachments-tabs .subsubsub { float:left; }
|
70 |
+
#attachments-tabs .subsubsub a { color:#21759b !important; }
|
71 |
+
#attachments-tabs-wrapper { border-bottom:1px solid #dfdfdf; position:relative; }
|
72 |
+
#attachments-tabs #sidemenu { overflow:hidden; zoom:1; background:#f9f9f9; float:none !important; margin:0; }
|
73 |
+
#attachments-live-filter { display:block; width:140px; float:left; margin:0 0 10px; }
|
deprecated/css/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php
|
deprecated/get-attachments.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( !defined( 'ABSPATH' ) ) exit;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Compares two array values with the same key "order"
|
8 |
+
*
|
9 |
+
* @param string $a First value
|
10 |
+
* @param string $b Second value
|
11 |
+
* @return int
|
12 |
+
* @author Jonathan Christopher
|
13 |
+
*/
|
14 |
+
function attachments_cmp($a, $b)
|
15 |
+
{
|
16 |
+
$a = intval( $a['order'] );
|
17 |
+
$b = intval( $b['order'] );
|
18 |
+
|
19 |
+
if( $a < $b )
|
20 |
+
{
|
21 |
+
return -1;
|
22 |
+
}
|
23 |
+
else if( $a > $b )
|
24 |
+
{
|
25 |
+
return 1;
|
26 |
+
}
|
27 |
+
else
|
28 |
+
{
|
29 |
+
return 0;
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Returns a formatted filesize
|
36 |
+
*
|
37 |
+
* @param string $path Path to file on disk
|
38 |
+
* @return string $formatted formatted filesize
|
39 |
+
* @author Jonathan Christopher
|
40 |
+
*/
|
41 |
+
function attachments_get_filesize_formatted( $path = NULL )
|
42 |
+
{
|
43 |
+
$formatted = '0 bytes';
|
44 |
+
if( file_exists( $path ) )
|
45 |
+
{
|
46 |
+
$formatted = size_format( @filesize( $path ) );
|
47 |
+
}
|
48 |
+
return $formatted;
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Retrieves all Attachments for provided Post or Page
|
54 |
+
*
|
55 |
+
* @param int $post_id (optional) ID of target Post or Page, otherwise pulls from global $post
|
56 |
+
* @return array $post_attachments
|
57 |
+
* @author Jonathan Christopher
|
58 |
+
* @author JR Tashjian
|
59 |
+
*/
|
60 |
+
|
61 |
+
function attachments_get_attachments( $post_id=null )
|
62 |
+
{
|
63 |
+
global $post;
|
64 |
+
|
65 |
+
if( $post_id==null )
|
66 |
+
{
|
67 |
+
$post_id = $post->ID;
|
68 |
+
}
|
69 |
+
|
70 |
+
// get all attachments
|
71 |
+
$existing_attachments = get_post_meta( $post_id, '_attachments', false );
|
72 |
+
|
73 |
+
// We can now proceed as normal, all legacy data should now be upgraded
|
74 |
+
|
75 |
+
$post_attachments = array();
|
76 |
+
|
77 |
+
if( is_array( $existing_attachments ) && count( $existing_attachments ) > 0 )
|
78 |
+
{
|
79 |
+
|
80 |
+
foreach ($existing_attachments as $attachment)
|
81 |
+
{
|
82 |
+
// decode and unserialize the data
|
83 |
+
$data = unserialize( base64_decode( $attachment ) );
|
84 |
+
|
85 |
+
array_push( $post_attachments, array(
|
86 |
+
'id' => stripslashes( $data['id'] ),
|
87 |
+
'name' => stripslashes( get_the_title( $data['id'] ) ),
|
88 |
+
'mime' => stripslashes( get_post_mime_type( $data['id'] ) ),
|
89 |
+
'title' => stripslashes( $data['title'] ),
|
90 |
+
'caption' => stripslashes( $data['caption'] ),
|
91 |
+
'filesize' => stripslashes( attachments_get_filesize_formatted( get_attached_file( $data['id'] ) ) ),
|
92 |
+
'location' => stripslashes( wp_get_attachment_url( $data['id'] ) ),
|
93 |
+
'order' => stripslashes( $data['order'] )
|
94 |
+
));
|
95 |
+
}
|
96 |
+
|
97 |
+
// sort attachments
|
98 |
+
if( count( $post_attachments ) > 1 )
|
99 |
+
{
|
100 |
+
usort( $post_attachments, "attachments_cmp" );
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
return $post_attachments;
|
105 |
+
}
|
deprecated/images/handle.gif
ADDED
Binary file
|
deprecated/images/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php
|
deprecated/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php
|
deprecated/js/attachments.js
ADDED
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(document).ready(function($){
|
2 |
+
var context = false;
|
3 |
+
var thickbox_modder;
|
4 |
+
|
5 |
+
// init sortability
|
6 |
+
if($('div#attachments-list ul:data(sortable)').length==0&&$('div#attachments-list ul li').length>0){
|
7 |
+
$('div#attachments-list ul').sortable({
|
8 |
+
containment: 'parent',
|
9 |
+
stop: function(e, ui) {
|
10 |
+
$('#attachments-list ul li').each(function(i, id) {
|
11 |
+
$(this).find('input.attachment_order').val(i+1);
|
12 |
+
});
|
13 |
+
}
|
14 |
+
});
|
15 |
+
}
|
16 |
+
|
17 |
+
// delete link handler
|
18 |
+
function attachments_hook_delete_links(theparent){
|
19 |
+
attachment_parent = theparent.parent().parent().parent();
|
20 |
+
attachment_parent.slideUp(function() {
|
21 |
+
attachment_parent.remove();
|
22 |
+
$('#attachments-list ul li').each(function(i, id) {
|
23 |
+
$(this).find('input.attachment_order').val(i+1);
|
24 |
+
});
|
25 |
+
if($('div#attachments-list li').length == 0) {
|
26 |
+
$('#attachments-list').slideUp(function() {
|
27 |
+
$('#attachments-list').hide();
|
28 |
+
});
|
29 |
+
}
|
30 |
+
});
|
31 |
+
}
|
32 |
+
|
33 |
+
// Hook our delete links
|
34 |
+
if(parseFloat($.fn.jquery)>=1.7){
|
35 |
+
// 'live' is deprecated
|
36 |
+
$(document).on("click", "span.attachment-delete a", function(event){
|
37 |
+
theparent = $(this);
|
38 |
+
attachments_hook_delete_links(theparent);
|
39 |
+
return false;
|
40 |
+
});
|
41 |
+
}else{
|
42 |
+
$('span.attachment-delete a').live('click',function(event){
|
43 |
+
theparent = $(this);
|
44 |
+
attachments_hook_delete_links(theparent);
|
45 |
+
return false;
|
46 |
+
});
|
47 |
+
}
|
48 |
+
|
49 |
+
|
50 |
+
|
51 |
+
// thickbox handler
|
52 |
+
if(parseFloat($.fn.jquery)>=1.7){
|
53 |
+
// 'live' is deprecated
|
54 |
+
$(document).on("click", "a#attachments-thickbox", function(event){
|
55 |
+
event.preventDefault();
|
56 |
+
theparent = $(this);
|
57 |
+
attachments_handle_thickbox(event,theparent);
|
58 |
+
return false;
|
59 |
+
});
|
60 |
+
}else{
|
61 |
+
$('a#attachments-thickbox').live('click',function(event){
|
62 |
+
event.preventDefault();
|
63 |
+
theparent = $(this);
|
64 |
+
attachments_handle_thickbox(event,theparent);
|
65 |
+
return false;
|
66 |
+
});
|
67 |
+
}
|
68 |
+
|
69 |
+
function attachments_handle_thickbox(event,theparent){
|
70 |
+
var href = theparent.attr('href'), width = jQuery(window).width(), H = jQuery(window).height(), W = ( 720 < width ) ? 720 : width;
|
71 |
+
if ( ! href ) return;
|
72 |
+
href = href.replace(/&width=[0-9]+/g, '');
|
73 |
+
href = href.replace(/&height=[0-9]+/g, '');
|
74 |
+
theparent.attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 ) );
|
75 |
+
context = true;
|
76 |
+
thickbox_modder = setInterval( function(){
|
77 |
+
if( context ){
|
78 |
+
modify_thickbox();
|
79 |
+
}
|
80 |
+
}, 500 );
|
81 |
+
tb_show('Attach a file', event.target.href, false);
|
82 |
+
return false;
|
83 |
+
}
|
84 |
+
|
85 |
+
// handle the attachment process
|
86 |
+
function handle_attach(title,caption,id,thumb){
|
87 |
+
var source = $('#attachment-template').html();
|
88 |
+
var template = Handlebars.compile(source);
|
89 |
+
|
90 |
+
var order = $('#attachments-list > ul > li').length + 1;
|
91 |
+
|
92 |
+
$('div#attachments-list ul', top.document).append(template({name:title,title:title,caption:caption,id:id,thumb:thumb,order:order}));
|
93 |
+
|
94 |
+
$('#attachments-list > ul > li').each(function(i, id) {
|
95 |
+
$(this).find('input.attachment_order').val(i+1);
|
96 |
+
});
|
97 |
+
|
98 |
+
return false;
|
99 |
+
}
|
100 |
+
|
101 |
+
|
102 |
+
function modify_thickbox(){
|
103 |
+
|
104 |
+
the_thickbox = jQuery('#TB_iframeContent').contents();
|
105 |
+
|
106 |
+
// our new click handler for the attach button
|
107 |
+
the_thickbox.find('td.savesend input').unbind('click').click(function(e){
|
108 |
+
|
109 |
+
jQuery(this).after('<span class="attachments-attached">Attached!</span>');
|
110 |
+
|
111 |
+
// grab our meta as per the Media library
|
112 |
+
var wp_media_meta = $(this).parent().parent().parent();
|
113 |
+
var wp_media_title = wp_media_meta.find('tr.post_title td.field input').val();
|
114 |
+
var wp_media_caption = wp_media_meta.find('tr.post_excerpt td.field input').val();
|
115 |
+
var wp_media_id = wp_media_meta.find('td.imgedit-response').attr('id').replace('imgedit-response-','');
|
116 |
+
var wp_media_thumb = wp_media_meta.parent().find('img.thumbnail').attr('src');
|
117 |
+
|
118 |
+
handle_attach(wp_media_title,wp_media_caption,wp_media_id,wp_media_thumb);
|
119 |
+
|
120 |
+
the_thickbox.find('span.attachments-attached').delay(1000).fadeOut('fast');
|
121 |
+
return false;
|
122 |
+
});
|
123 |
+
// update button
|
124 |
+
if(the_thickbox.find('.media-item .savesend input[type=submit], #insertonlybutton').length){
|
125 |
+
the_thickbox.find('.media-item .savesend input[type=submit], #insertonlybutton').val('Attach');
|
126 |
+
}
|
127 |
+
if(the_thickbox.find('#tab-type_url').length){
|
128 |
+
the_thickbox.find('#tab-type_url').hide();
|
129 |
+
}
|
130 |
+
if(the_thickbox.find('tr.post_title').length){
|
131 |
+
// we need to ALWAYS get the fullsize since we're retrieving the guid
|
132 |
+
// if the user inserts an image somewhere else and chooses another size, everything breaks
|
133 |
+
the_thickbox.find('tr.image-size input[value="full"]').prop('checked', true);
|
134 |
+
the_thickbox.find('tr.post_title,tr.image_alt,tr.post_excerpt,tr.image-size,tr.post_content,tr.url,tr.align,tr.submit>td>a.del-link').hide();
|
135 |
+
}
|
136 |
+
|
137 |
+
// was the thickbox closed?
|
138 |
+
if(the_thickbox.length==0 && context){
|
139 |
+
clearInterval(thickbox_modder);
|
140 |
+
context = false;
|
141 |
+
}
|
142 |
+
}
|
143 |
+
|
144 |
+
});
|
145 |
+
|
146 |
+
|
{js → deprecated/js}/handlebars.js
RENAMED
File without changes
|
deprecated/js/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php
|
{languages → deprecated/languages}/attachments-fr_FR.mo
RENAMED
File without changes
|
{languages → deprecated/languages}/attachments-fr_FR.po
RENAMED
File without changes
|
{languages → deprecated/languages}/attachments-it_IT.mo
RENAMED
File without changes
|
{languages → deprecated/languages}/attachments-it_IT.po
RENAMED
File without changes
|
{languages → deprecated/languages}/attachments-pl_PL.mo
RENAMED
File without changes
|
{languages → deprecated/languages}/attachments-pl_PL.po
RENAMED
File without changes
|
{languages → deprecated/languages}/attachments-pt_BR.mo
RENAMED
File without changes
|
{languages → deprecated/languages}/attachments-pt_BR.po
RENAMED
File without changes
|
{languages → deprecated/languages}/attachments-sv_SE.mo
RENAMED
File without changes
|
{languages → deprecated/languages}/attachments-sv_SE.po
RENAMED
File without changes
|
deprecated/languages/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php
|
humans.txt
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* TEAM */
|
2 |
+
Name: Jonathan Christopher
|
3 |
+
Site: http://mondaybynoon.com
|
4 |
+
Title: Lead Developer
|
5 |
+
Twitter: @jchristopher
|
6 |
+
ADN: @jchristopher
|
7 |
+
Location: Troy, NY, USA
|
8 |
+
|
9 |
+
/* THANKS */
|
10 |
+
JR Tashjian http://jrtashjian.com
|
11 |
+
|
12 |
+
/* META */
|
13 |
+
Updated: 2012/12/01
|
14 |
+
Standards: HTML5, CSS3
|
15 |
+
Components: WordPress, jQuery, Underscore.js, Backbone.js
|
16 |
+
Software: Sublime Text 2
|
images/handle.gif
CHANGED
Binary file
|
images/index.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Do not modify the files in this folder.
|
5 |
+
*/
|
index.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Plugin Name: Attachments
|
5 |
+
* Plugin URI: https://github.com/jchristopher/attachments
|
6 |
+
* Description: Attachments gives the ability to append any number of Media Library items to Pages, Posts, and Custom Post Types
|
7 |
+
* Author: Jonathan Christopher
|
8 |
+
* Author URI: http://mondaybynoon.com/
|
9 |
+
* Version: 3.0.6
|
10 |
+
* Text Domain: attachments
|
11 |
+
* Domain Path: /languages/
|
12 |
+
* License: GPLv2 or later
|
13 |
+
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
14 |
+
*/
|
15 |
+
|
16 |
+
// Exit if accessed directly
|
17 |
+
if( !defined( 'ABSPATH' ) ) exit;
|
18 |
+
|
19 |
+
// Store whether or not we're in the admin
|
20 |
+
if( !defined( 'IS_ADMIN' ) ) define( 'IS_ADMIN', is_admin() );
|
21 |
+
|
22 |
+
// Environment check
|
23 |
+
$wp_version = get_bloginfo( 'version' );
|
24 |
+
|
25 |
+
if( !version_compare( PHP_VERSION, '5.2', '>=' ) && IS_ADMIN && ( !defined( 'DOING_AJAX' ) || !DOING_AJAX ) )
|
26 |
+
{
|
27 |
+
// failed PHP requirement
|
28 |
+
require_once ABSPATH . '/wp-admin/includes/plugin.php';
|
29 |
+
deactivate_plugins( __FILE__ );
|
30 |
+
wp_die( esc_attr( __( 'Attachments requires PHP 5.2+. Attachments has been automatically deactivated.' ) ) );
|
31 |
+
}
|
32 |
+
else
|
33 |
+
{
|
34 |
+
if( ( defined( 'ATTACHMENTS_LEGACY' ) && ATTACHMENTS_LEGACY === true ) || version_compare( $wp_version, '3.5', '<' ) )
|
35 |
+
{
|
36 |
+
// load deprecated version of Attachments
|
37 |
+
require_once 'deprecated/attachments.php';
|
38 |
+
}
|
39 |
+
else
|
40 |
+
{
|
41 |
+
define( 'ATTACHMENTS_DIR', plugin_dir_path( __FILE__ ) );
|
42 |
+
define( 'ATTACHMENTS_URL', plugin_dir_url( __FILE__ ) );
|
43 |
+
|
44 |
+
// load current version of Attachments
|
45 |
+
require_once 'classes/class.attachments.php';
|
46 |
+
}
|
47 |
+
}
|
js/attachments.js
CHANGED
@@ -1,146 +1,90 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
//
|
18 |
-
|
19 |
-
|
20 |
-
attachment_parent.slideUp(function() {
|
21 |
-
attachment_parent.remove();
|
22 |
-
$('#attachments-list ul li').each(function(i, id) {
|
23 |
-
$(this).find('input.attachment_order').val(i+1);
|
24 |
-
});
|
25 |
-
if($('div#attachments-list li').length == 0) {
|
26 |
-
$('#attachments-list').slideUp(function() {
|
27 |
-
$('#attachments-list').hide();
|
28 |
-
});
|
29 |
-
}
|
30 |
-
});
|
31 |
}
|
32 |
-
|
33 |
-
|
34 |
-
if(parseFloat($.fn.jquery)>=1.7){
|
35 |
-
// 'live' is deprecated
|
36 |
-
$(document).on("click", "span.attachment-delete a", function(event){
|
37 |
-
theparent = $(this);
|
38 |
-
attachments_hook_delete_links(theparent);
|
39 |
-
return false;
|
40 |
-
});
|
41 |
-
}else{
|
42 |
-
$('span.attachment-delete a').live('click',function(event){
|
43 |
-
theparent = $(this);
|
44 |
-
attachments_hook_delete_links(theparent);
|
45 |
-
return false;
|
46 |
-
});
|
47 |
}
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
}
|
|
|
|
|
|
|
|
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
// handle the attachment process
|
86 |
-
function handle_attach(title,caption,id,thumb){
|
87 |
-
var source = $('#attachment-template').html();
|
88 |
-
var template = Handlebars.compile(source);
|
89 |
-
|
90 |
-
var order = $('#attachments-list > ul > li').length + 1;
|
91 |
-
|
92 |
-
$('div#attachments-list ul', top.document).append(template({name:title,title:title,caption:caption,id:id,thumb:thumb,order:order}));
|
93 |
-
|
94 |
-
$('#attachments-list > ul > li').each(function(i, id) {
|
95 |
-
$(this).find('input.attachment_order').val(i+1);
|
96 |
-
});
|
97 |
-
|
98 |
-
return false;
|
99 |
-
}
|
100 |
-
|
101 |
-
|
102 |
-
function modify_thickbox(){
|
103 |
-
|
104 |
-
the_thickbox = jQuery('#TB_iframeContent').contents();
|
105 |
-
|
106 |
-
// our new click handler for the attach button
|
107 |
-
the_thickbox.find('td.savesend input').unbind('click').click(function(e){
|
108 |
-
|
109 |
-
jQuery(this).after('<span class="attachments-attached">Attached!</span>');
|
110 |
-
|
111 |
-
// grab our meta as per the Media library
|
112 |
-
var wp_media_meta = $(this).parent().parent().parent();
|
113 |
-
var wp_media_title = wp_media_meta.find('tr.post_title td.field input').val();
|
114 |
-
var wp_media_caption = wp_media_meta.find('tr.post_excerpt td.field input').val();
|
115 |
-
var wp_media_id = wp_media_meta.find('td.imgedit-response').attr('id').replace('imgedit-response-','');
|
116 |
-
var wp_media_thumb = wp_media_meta.parent().find('img.thumbnail').attr('src');
|
117 |
-
|
118 |
-
handle_attach(wp_media_title,wp_media_caption,wp_media_id,wp_media_thumb);
|
119 |
-
|
120 |
-
the_thickbox.find('span.attachments-attached').delay(1000).fadeOut('fast');
|
121 |
-
return false;
|
122 |
-
});
|
123 |
-
// update button
|
124 |
-
if(the_thickbox.find('.media-item .savesend input[type=submit], #insertonlybutton').length){
|
125 |
-
the_thickbox.find('.media-item .savesend input[type=submit], #insertonlybutton').val('Attach');
|
126 |
-
}
|
127 |
-
if(the_thickbox.find('#tab-type_url').length){
|
128 |
-
the_thickbox.find('#tab-type_url').hide();
|
129 |
-
}
|
130 |
-
if(the_thickbox.find('tr.post_title').length){
|
131 |
-
// we need to ALWAYS get the fullsize since we're retrieving the guid
|
132 |
-
// if the user inserts an image somewhere else and chooses another size, everything breaks
|
133 |
-
the_thickbox.find('tr.image-size input[value="full"]').prop('checked', true);
|
134 |
-
the_thickbox.find('tr.post_title,tr.image_alt,tr.post_excerpt,tr.image-size,tr.post_content,tr.url,tr.align,tr.submit>td>a.del-link').hide();
|
135 |
-
}
|
136 |
-
|
137 |
-
// was the thickbox closed?
|
138 |
-
if(the_thickbox.length==0 && context){
|
139 |
-
clearInterval(thickbox_modder);
|
140 |
-
context = false;
|
141 |
-
}
|
142 |
-
}
|
143 |
-
|
144 |
-
});
|
145 |
-
|
146 |
-
|
1 |
+
function attachments_uniqid (prefix, more_entropy) {
|
2 |
+
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
3 |
+
// + revised by: Kankrelune (http://www.webfaktory.info/)
|
4 |
+
// % note 1: Uses an internal counter (in php_js global) to avoid collision
|
5 |
+
// * example 1: uniqid();
|
6 |
+
// * returns 1: 'a30285b160c14'
|
7 |
+
// * example 2: uniqid('foo');
|
8 |
+
// * returns 2: 'fooa30285b1cd361'
|
9 |
+
// * example 3: uniqid('bar', true);
|
10 |
+
// * returns 3: 'bara20285b23dfd1.31879087'
|
11 |
+
if (typeof prefix == 'undefined') {
|
12 |
+
prefix = "";
|
13 |
+
}
|
14 |
+
|
15 |
+
var retId;
|
16 |
+
var formatSeed = function (seed, reqWidth) {
|
17 |
+
seed = parseInt(seed, 10).toString(16); // to hex str
|
18 |
+
if (reqWidth < seed.length) { // so long we split
|
19 |
+
return seed.slice(seed.length - reqWidth);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
+
if (reqWidth > seed.length) { // so short we pad
|
22 |
+
return Array(1 + (reqWidth - seed.length)).join('0') + seed;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
}
|
24 |
+
return seed;
|
25 |
+
};
|
26 |
+
|
27 |
+
// BEGIN REDUNDANT
|
28 |
+
if (!this.php_js) {
|
29 |
+
this.php_js = {};
|
30 |
+
}
|
31 |
+
// END REDUNDANT
|
32 |
+
if (!this.php_js.uniqidSeed) { // init seed with big random int
|
33 |
+
this.php_js.uniqidSeed = Math.floor(Math.random() * 0x75bcd15);
|
34 |
+
}
|
35 |
+
this.php_js.uniqidSeed++;
|
36 |
+
|
37 |
+
retId = prefix; // start with prefix, add current milliseconds hex string
|
38 |
+
retId += formatSeed(parseInt(new Date().getTime() / 1000, 10), 8);
|
39 |
+
retId += formatSeed(this.php_js.uniqidSeed, 5); // add seed hex string
|
40 |
+
if (more_entropy) {
|
41 |
+
// for more entropy we add a float lower to 10
|
42 |
+
retId += (Math.random() * 10).toFixed(8).toString();
|
43 |
+
}
|
44 |
+
|
45 |
+
return retId;
|
46 |
+
}
|
47 |
+
|
48 |
+
function attachments_isset () {
|
49 |
+
// http://kevin.vanzonneveld.net
|
50 |
+
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
51 |
+
// + improved by: FremyCompany
|
52 |
+
// + improved by: Onno Marsman
|
53 |
+
// + improved by: Rafał Kukawski
|
54 |
+
// * example 1: isset( undefined, true);
|
55 |
+
// * returns 1: false
|
56 |
+
// * example 2: isset( 'Kevin van Zonneveld' );
|
57 |
+
// * returns 2: true
|
58 |
+
var a = arguments,
|
59 |
+
l = a.length,
|
60 |
+
i = 0,
|
61 |
+
undef;
|
62 |
+
|
63 |
+
if (l === 0) {
|
64 |
+
throw new Error('Empty isset');
|
65 |
+
}
|
66 |
+
|
67 |
+
while (i !== l) {
|
68 |
+
if (a[i] === undef || a[i] === null) {
|
69 |
+
return false;
|
70 |
}
|
71 |
+
i++;
|
72 |
+
}
|
73 |
+
return true;
|
74 |
+
}
|
75 |
|
76 |
+
jQuery(document).ready(function($){
|
77 |
+
$( '.attachments-container' ).sortable({
|
78 |
+
placeholder: 'attachments-attachment-highlight',
|
79 |
+
opacity: 0.5,
|
80 |
+
forceHelperSize: true,
|
81 |
+
forcePlaceholderSize: true,
|
82 |
+
items: '> .attachments-attachment',
|
83 |
+
scroll: true,
|
84 |
+
tolerance: 'intersect',
|
85 |
+
axis: 'y',
|
86 |
+
containment: 'parent',
|
87 |
+
handle: '.attachments-handle img'
|
88 |
+
});
|
89 |
+
$( '.attachments-container' ).disableSelection();
|
90 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/index.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Do not modify the files in this folder.
|
5 |
+
*/
|
languages/index.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Do not modify the files in this folder.
|
5 |
+
*/
|
license.txt
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
+
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
5 |
+
51 Franklin St, Fifth Floor, Boston, MA 02110, USA
|
6 |
+
|
7 |
+
Everyone is permitted to copy and distribute verbatim copies
|
8 |
+
of this license document, but changing it is not allowed.
|
9 |
+
|
10 |
+
Preamble
|
11 |
+
|
12 |
+
The licenses for most software are designed to take away your
|
13 |
+
freedom to share and change it. By contrast, the GNU General Public
|
14 |
+
License is intended to guarantee your freedom to share and change free
|
15 |
+
software--to make sure the software is free for all its users. This
|
16 |
+
General Public License applies to most of the Free Software
|
17 |
+
Foundation's software and to any other program whose authors commit to
|
18 |
+
using it. (Some other Free Software Foundation software is covered by
|
19 |
+
the GNU Library General Public License instead.) You can apply it to
|
20 |
+
your programs, too.
|
21 |
+
|
22 |
+
When we speak of free software, we are referring to freedom, not
|
23 |
+
price. Our General Public Licenses are designed to make sure that you
|
24 |
+
have the freedom to distribute copies of free software (and charge for
|
25 |
+
this service if you wish), that you receive source code or can get it
|
26 |
+
if you want it, that you can change the software or use pieces of it
|
27 |
+
in new free programs; and that you know you can do these things.
|
28 |
+
|
29 |
+
To protect your rights, we need to make restrictions that forbid
|
30 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
31 |
+
These restrictions translate to certain responsibilities for you if you
|
32 |
+
distribute copies of the software, or if you modify it.
|
33 |
+
|
34 |
+
For example, if you distribute copies of such a program, whether
|
35 |
+
gratis or for a fee, you must give the recipients all the rights that
|
36 |
+
you have. You must make sure that they, too, receive or can get the
|
37 |
+
source code. And you must show them these terms so they know their
|
38 |
+
rights.
|
39 |
+
|
40 |
+
We protect your rights with two steps: (1) copyright the software, and
|
41 |
+
(2) offer you this license which gives you legal permission to copy,
|
42 |
+
distribute and/or modify the software.
|
43 |
+
|
44 |
+
Also, for each author's protection and ours, we want to make certain
|
45 |
+
that everyone understands that there is no warranty for this free
|
46 |
+
software. If the software is modified by someone else and passed on, we
|
47 |
+
want its recipients to know that what they have is not the original, so
|
48 |
+
that any problems introduced by others will not reflect on the original
|
49 |
+
authors' reputations.
|
50 |
+
|
51 |
+
Finally, any free program is threatened constantly by software
|
52 |
+
patents. We wish to avoid the danger that redistributors of a free
|
53 |
+
program will individually obtain patent licenses, in effect making the
|
54 |
+
program proprietary. To prevent this, we have made it clear that any
|
55 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
56 |
+
|
57 |
+
The precise terms and conditions for copying, distribution and
|
58 |
+
modification follow.
|
59 |
+
|
60 |
+
GNU GENERAL PUBLIC LICENSE
|
61 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
62 |
+
|
63 |
+
0. This License applies to any program or other work which contains
|
64 |
+
a notice placed by the copyright holder saying it may be distributed
|
65 |
+
under the terms of this General Public License. The "Program", below,
|
66 |
+
refers to any such program or work, and a "work based on the Program"
|
67 |
+
means either the Program or any derivative work under copyright law:
|
68 |
+
that is to say, a work containing the Program or a portion of it,
|
69 |
+
either verbatim or with modifications and/or translated into another
|
70 |
+
language. (Hereinafter, translation is included without limitation in
|
71 |
+
the term "modification".) Each licensee is addressed as "you".
|
72 |
+
|
73 |
+
Activities other than copying, distribution and modification are not
|
74 |
+
covered by this License; they are outside its scope. The act of
|
75 |
+
running the Program is not restricted, and the output from the Program
|
76 |
+
is covered only if its contents constitute a work based on the
|
77 |
+
Program (independent of having been made by running the Program).
|
78 |
+
Whether that is true depends on what the Program does.
|
79 |
+
|
80 |
+
1. You may copy and distribute verbatim copies of the Program's
|
81 |
+
source code as you receive it, in any medium, provided that you
|
82 |
+
conspicuously and appropriately publish on each copy an appropriate
|
83 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
84 |
+
notices that refer to this License and to the absence of any warranty;
|
85 |
+
and give any other recipients of the Program a copy of this License
|
86 |
+
along with the Program.
|
87 |
+
|
88 |
+
You may charge a fee for the physical act of transferring a copy, and
|
89 |
+
you may at your option offer warranty protection in exchange for a fee.
|
90 |
+
|
91 |
+
2. You may modify your copy or copies of the Program or any portion
|
92 |
+
of it, thus forming a work based on the Program, and copy and
|
93 |
+
distribute such modifications or work under the terms of Section 1
|
94 |
+
above, provided that you also meet all of these conditions:
|
95 |
+
|
96 |
+
a) You must cause the modified files to carry prominent notices
|
97 |
+
stating that you changed the files and the date of any change.
|
98 |
+
|
99 |
+
b) You must cause any work that you distribute or publish, that in
|
100 |
+
whole or in part contains or is derived from the Program or any
|
101 |
+
part thereof, to be licensed as a whole at no charge to all third
|
102 |
+
parties under the terms of this License.
|
103 |
+
|
104 |
+
c) If the modified program normally reads commands interactively
|
105 |
+
when run, you must cause it, when started running for such
|
106 |
+
interactive use in the most ordinary way, to print or display an
|
107 |
+
announcement including an appropriate copyright notice and a
|
108 |
+
notice that there is no warranty (or else, saying that you provide
|
109 |
+
a warranty) and that users may redistribute the program under
|
110 |
+
these conditions, and telling the user how to view a copy of this
|
111 |
+
License. (Exception: if the Program itself is interactive but
|
112 |
+
does not normally print such an announcement, your work based on
|
113 |
+
the Program is not required to print an announcement.)
|
114 |
+
|
115 |
+
These requirements apply to the modified work as a whole. If
|
116 |
+
identifiable sections of that work are not derived from the Program,
|
117 |
+
and can be reasonably considered independent and separate works in
|
118 |
+
themselves, then this License, and its terms, do not apply to those
|
119 |
+
sections when you distribute them as separate works. But when you
|
120 |
+
distribute the same sections as part of a whole which is a work based
|
121 |
+
on the Program, the distribution of the whole must be on the terms of
|
122 |
+
this License, whose permissions for other licensees extend to the
|
123 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
124 |
+
Thus, it is not the intent of this section to claim rights or contest
|
125 |
+
your rights to work written entirely by you; rather, the intent is to
|
126 |
+
exercise the right to control the distribution of derivative or
|
127 |
+
collective works based on the Program.
|
128 |
+
|
129 |
+
In addition, mere aggregation of another work not based on the Program
|
130 |
+
with the Program (or with a work based on the Program) on a volume of
|
131 |
+
a storage or distribution medium does not bring the other work under
|
132 |
+
the scope of this License.
|
133 |
+
|
134 |
+
3. You may copy and distribute the Program (or a work based on it,
|
135 |
+
under Section 2) in object code or executable form under the terms of
|
136 |
+
Sections 1 and 2 above provided that you also do one of the following:
|
137 |
+
|
138 |
+
a) Accompany it with the complete corresponding machine-readable
|
139 |
+
source code, which must be distributed under the terms of Sections
|
140 |
+
1 and 2 above on a medium customarily used for software interchange; or,
|
141 |
+
|
142 |
+
b) Accompany it with a written offer, valid for at least three
|
143 |
+
years, to give any third party, for a charge no more than your
|
144 |
+
cost of physically performing source distribution, a complete
|
145 |
+
machine-readable copy of the corresponding source code, to be
|
146 |
+
distributed under the terms of Sections 1 and 2 above on a medium
|
147 |
+
customarily used for software interchange; or,
|
148 |
+
|
149 |
+
c) Accompany it with the information you received as to the offer
|
150 |
+
to distribute corresponding source code. (This alternative is
|
151 |
+
allowed only for noncommercial distribution and only if you
|
152 |
+
received the program in object code or executable form with such
|
153 |
+
an offer, in accord with Subsection b above.)
|
154 |
+
|
155 |
+
The source code for a work means the preferred form of the work for
|
156 |
+
making modifications to it. For an executable work, complete source
|
157 |
+
code means all the source code for all modules it contains, plus any
|
158 |
+
associated interface definition files, plus the scripts used to
|
159 |
+
control compilation and installation of the executable. However, as a
|
160 |
+
special exception, the source code distributed need not include
|
161 |
+
anything that is normally distributed (in either source or binary
|
162 |
+
form) with the major components (compiler, kernel, and so on) of the
|
163 |
+
operating system on which the executable runs, unless that component
|
164 |
+
itself accompanies the executable.
|
165 |
+
|
166 |
+
If distribution of executable or object code is made by offering
|
167 |
+
access to copy from a designated place, then offering equivalent
|
168 |
+
access to copy the source code from the same place counts as
|
169 |
+
distribution of the source code, even though third parties are not
|
170 |
+
compelled to copy the source along with the object code.
|
171 |
+
|
172 |
+
4. You may not copy, modify, sublicense, or distribute the Program
|
173 |
+
except as expressly provided under this License. Any attempt
|
174 |
+
otherwise to copy, modify, sublicense or distribute the Program is
|
175 |
+
void, and will automatically terminate your rights under this License.
|
176 |
+
However, parties who have received copies, or rights, from you under
|
177 |
+
this License will not have their licenses terminated so long as such
|
178 |
+
parties remain in full compliance.
|
179 |
+
|
180 |
+
5. You are not required to accept this License, since you have not
|
181 |
+
signed it. However, nothing else grants you permission to modify or
|
182 |
+
distribute the Program or its derivative works. These actions are
|
183 |
+
prohibited by law if you do not accept this License. Therefore, by
|
184 |
+
modifying or distributing the Program (or any work based on the
|
185 |
+
Program), you indicate your acceptance of this License to do so, and
|
186 |
+
all its terms and conditions for copying, distributing or modifying
|
187 |
+
the Program or works based on it.
|
188 |
+
|
189 |
+
6. Each time you redistribute the Program (or any work based on the
|
190 |
+
Program), the recipient automatically receives a license from the
|
191 |
+
original licensor to copy, distribute or modify the Program subject to
|
192 |
+
these terms and conditions. You may not impose any further
|
193 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
194 |
+
You are not responsible for enforcing compliance by third parties to
|
195 |
+
this License.
|
196 |
+
|
197 |
+
7. If, as a consequence of a court judgment or allegation of patent
|
198 |
+
infringement or for any other reason (not limited to patent issues),
|
199 |
+
conditions are imposed on you (whether by court order, agreement or
|
200 |
+
otherwise) that contradict the conditions of this License, they do not
|
201 |
+
excuse you from the conditions of this License. If you cannot
|
202 |
+
distribute so as to satisfy simultaneously your obligations under this
|
203 |
+
License and any other pertinent obligations, then as a consequence you
|
204 |
+
may not distribute the Program at all. For example, if a patent
|
205 |
+
license would not permit royalty-free redistribution of the Program by
|
206 |
+
all those who receive copies directly or indirectly through you, then
|
207 |
+
the only way you could satisfy both it and this License would be to
|
208 |
+
refrain entirely from distribution of the Program.
|
209 |
+
|
210 |
+
If any portion of this section is held invalid or unenforceable under
|
211 |
+
any particular circumstance, the balance of the section is intended to
|
212 |
+
apply and the section as a whole is intended to apply in other
|
213 |
+
circumstances.
|
214 |
+
|
215 |
+
It is not the purpose of this section to induce you to infringe any
|
216 |
+
patents or other property right claims or to contest validity of any
|
217 |
+
such claims; this section has the sole purpose of protecting the
|
218 |
+
integrity of the free software distribution system, which is
|
219 |
+
implemented by public license practices. Many people have made
|
220 |
+
generous contributions to the wide range of software distributed
|
221 |
+
through that system in reliance on consistent application of that
|
222 |
+
system; it is up to the author/donor to decide if he or she is willing
|
223 |
+
to distribute software through any other system and a licensee cannot
|
224 |
+
impose that choice.
|
225 |
+
|
226 |
+
This section is intended to make thoroughly clear what is believed to
|
227 |
+
be a consequence of the rest of this License.
|
228 |
+
|
229 |
+
8. If the distribution and/or use of the Program is restricted in
|
230 |
+
certain countries either by patents or by copyrighted interfaces, the
|
231 |
+
original copyright holder who places the Program under this License
|
232 |
+
may add an explicit geographical distribution limitation excluding
|
233 |
+
those countries, so that distribution is permitted only in or among
|
234 |
+
countries not thus excluded. In such case, this License incorporates
|
235 |
+
the limitation as if written in the body of this License.
|
236 |
+
|
237 |
+
9. The Free Software Foundation may publish revised and/or new versions
|
238 |
+
of the General Public License from time to time. Such new versions will
|
239 |
+
be similar in spirit to the present version, but may differ in detail to
|
240 |
+
address new problems or concerns.
|
241 |
+
|
242 |
+
Each version is given a distinguishing version number. If the Program
|
243 |
+
specifies a version number of this License which applies to it and "any
|
244 |
+
later version", you have the option of following the terms and conditions
|
245 |
+
either of that version or of any later version published by the Free
|
246 |
+
Software Foundation. If the Program does not specify a version number of
|
247 |
+
this License, you may choose any version ever published by the Free Software
|
248 |
+
Foundation.
|
249 |
+
|
250 |
+
10. If you wish to incorporate parts of the Program into other free
|
251 |
+
programs whose distribution conditions are different, write to the author
|
252 |
+
to ask for permission. For software which is copyrighted by the Free
|
253 |
+
Software Foundation, write to the Free Software Foundation; we sometimes
|
254 |
+
make exceptions for this. Our decision will be guided by the two goals
|
255 |
+
of preserving the free status of all derivatives of our free software and
|
256 |
+
of promoting the sharing and reuse of software generally.
|
257 |
+
|
258 |
+
NO WARRANTY
|
259 |
+
|
260 |
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
+
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
262 |
+
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
263 |
+
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
264 |
+
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
265 |
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
266 |
+
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
267 |
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
268 |
+
REPAIR OR CORRECTION.
|
269 |
+
|
270 |
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
271 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
272 |
+
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
273 |
+
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
274 |
+
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
275 |
+
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
276 |
+
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
277 |
+
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
+
POSSIBILITY OF SUCH DAMAGES.
|
279 |
+
|
280 |
+
END OF TERMS AND CONDITIONS
|
281 |
+
|
readme.txt
CHANGED
@@ -3,8 +3,10 @@ Contributors: jchristopher
|
|
3 |
Donate link: http://mondaybynoon.com/donate/
|
4 |
Tags: post, page, posts, pages, images, PDF, doc, Word, image, jpg, jpeg, picture, pictures, photos, attachment
|
5 |
Requires at least: 3.0
|
6 |
-
Tested up to: 3.
|
7 |
-
Stable tag:
|
|
|
|
|
8 |
|
9 |
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types
|
10 |
|
@@ -12,12 +14,48 @@ Attachments allows you to simply append any number of items from your WordPress
|
|
12 |
|
13 |
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types. This plugin *does not* directly interact with your theme, you will need to edit your template files.
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
== Installation ==
|
16 |
|
17 |
1. Download the plugin and extract the files
|
18 |
1. Upload `attachments` to your `~/wp-content/plugins/` directory
|
19 |
1. Activate the plugin through the 'Plugins' menu in WordPress
|
20 |
-
1.
|
21 |
1. Update your templates where applicable (see **Usage**)
|
22 |
|
23 |
== Frequently Asked Questions ==
|
@@ -30,6 +68,14 @@ You need to turn on Attachments for your post types. View the Attachments settin
|
|
30 |
|
31 |
You will need to edit your theme files where applicable. Please reference the **Usage** instructions.
|
32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
= Where are uploads saved? =
|
34 |
|
35 |
Attachments uses WordPress' built in Media library for uploads and storage.
|
@@ -40,12 +86,52 @@ Attachments uses WordPress' built in Media library for uploads and storage.
|
|
40 |
|
41 |
== Screenshots ==
|
42 |
|
43 |
-
1. Attachments meta box
|
44 |
-
2.
|
45 |
-
|
|
|
|
|
46 |
|
47 |
== Changelog ==
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
= 1.6.2.1 =
|
50 |
* Fixed an issue with Handlebars in Firefox
|
51 |
* Better handling of Attachment name
|
@@ -177,6 +263,13 @@ Attachments uses WordPress' built in Media library for uploads and storage.
|
|
177 |
|
178 |
== Upgrade Notice ==
|
179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
= 1.0.8 =
|
181 |
As always, be sure to back up your database and files before upgrading.
|
182 |
|
@@ -187,40 +280,129 @@ Attachments are now stored in such a way that removes an in-place limitation on
|
|
187 |
|
188 |
Planned feature additions include:
|
189 |
|
190 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
|
192 |
== Usage ==
|
193 |
|
194 |
-
|
195 |
|
196 |
-
|
|
|
197 |
|
198 |
-
|
199 |
|
200 |
-
|
201 |
-
* **caption** - The attachment Caption
|
202 |
-
* **id** - The WordPress assigned attachment id (for use with other WordPress media functions)
|
203 |
-
* **location** - The attachment URI
|
204 |
-
* **mime** - The attachment MIME type (as defined by WordPress)
|
205 |
-
* **filesize** - Formatted file size
|
206 |
|
207 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
|
209 |
`<?php
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
<
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
Donate link: http://mondaybynoon.com/donate/
|
4 |
Tags: post, page, posts, pages, images, PDF, doc, Word, image, jpg, jpeg, picture, pictures, photos, attachment
|
5 |
Requires at least: 3.0
|
6 |
+
Tested up to: 3.5
|
7 |
+
Stable tag: 3.0.6
|
8 |
+
License: GPLv2 or later
|
9 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
11 |
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types
|
12 |
|
14 |
|
15 |
Attachments allows you to simply append any number of items from your WordPress Media Library to Posts, Pages, and Custom Post Types. This plugin *does not* directly interact with your theme, you will need to edit your template files.
|
16 |
|
17 |
+
= Updated for WordPress 3.5! =
|
18 |
+
|
19 |
+
WordPress 3.5 ships with an amazing new Media workflow and Attachments 3.0 makes great use of it. *If you are not running WordPress 3.5, version 1.6.2.1 will be used until you upgrade to WordPress 3.5.*
|
20 |
+
|
21 |
+
= Associate Media items with posts =
|
22 |
+
|
23 |
+
The idea behind Attachments is to give developers the ability to directly associate Media items with any post. This is accomplished by adding a meta box to post edit screens as determined by the developer. Once Media items have been associated with a post, you're able to retrieve those Attachments and include them directly within your template files using any specific markup you wish.
|
24 |
+
|
25 |
+
= Integrate Attachments within your theme with fine grained control =
|
26 |
+
|
27 |
+
**Attachments does not automatically integrate itself with your theme.** Since the idea behind Attachments is to allow integration of Media within posts using developer-crafted, unique markup, *it's up to you to integrate with your theme*. The most basic integration includes editing the [appropriate template file](http://codex.wordpress.org/Template_Hierarchy) and adding your call(s) to Attachments. For example, if you have set up Attachments to be used with your Posts entries, edit `single.php` to include the following within The Loop:
|
28 |
+
|
29 |
+
`<?php $attachments = new Attachments( 'attachments' ); /* pass the instance name */ ?>
|
30 |
+
<?php if( $attachments->exist() ) : ?>
|
31 |
+
<h3>Attachments</h3>
|
32 |
+
<ul>
|
33 |
+
<?php while( $attachments->get() ) : ?>
|
34 |
+
<li>
|
35 |
+
ID: <?php echo $attachments->id(); ?><br />
|
36 |
+
Type: <?php echo $attachments->type(); ?><br />
|
37 |
+
Subtype: <?php echo $attachments->subtype(); ?><br />
|
38 |
+
URL: <?php echo $attachments->url(); ?><br />
|
39 |
+
Image: <?php echo $attachments->image( 'thumbnail' ); ?><br />
|
40 |
+
Source: <?php echo $attachments->src( 'full' ); ?><br />
|
41 |
+
Size: <?php echo $attachments->filesize(); ?><br />
|
42 |
+
Title Field: <?php echo $attachments->field( 'title' ); ?><br />
|
43 |
+
Caption Field: <?php echo $attachments->field( 'caption' ); ?>
|
44 |
+
</li>
|
45 |
+
<?php endwhile; ?>
|
46 |
+
</ul>
|
47 |
+
<?php endif; ?>`
|
48 |
+
|
49 |
+
That snippet will request all of the existing Attachments defined for the current Post within The Loop, and retrieve each itemized property for that Attachment. Using the provided details you're able to integrate the attached Media items in any way you please.
|
50 |
+
|
51 |
+
There is a lot more information on [Attachments' GitHub page](https://github.com/jchristopher/attachments). Please contribute!
|
52 |
+
|
53 |
== Installation ==
|
54 |
|
55 |
1. Download the plugin and extract the files
|
56 |
1. Upload `attachments` to your `~/wp-content/plugins/` directory
|
57 |
1. Activate the plugin through the 'Plugins' menu in WordPress
|
58 |
+
1. Implement Attachments in your theme's `functions.php` or your own plugin (see **Usage**)
|
59 |
1. Update your templates where applicable (see **Usage**)
|
60 |
|
61 |
== Frequently Asked Questions ==
|
68 |
|
69 |
You will need to edit your theme files where applicable. Please reference the **Usage** instructions.
|
70 |
|
71 |
+
= How do I disable the default Attachments meta box? =
|
72 |
+
|
73 |
+
You will need to edit your Attachments configuration. Please reference the **Usage** instructions.
|
74 |
+
|
75 |
+
= How do I change the fields for each Attachment? =
|
76 |
+
|
77 |
+
You will need to edit your Attachments configuration. Please reference the **Usage** instructions.
|
78 |
+
|
79 |
= Where are uploads saved? =
|
80 |
|
81 |
Attachments uses WordPress' built in Media library for uploads and storage.
|
86 |
|
87 |
== Screenshots ==
|
88 |
|
89 |
+
1. An Attachments meta box sitting below the content editor
|
90 |
+
2. Direct integration with WordPress 3.5+ Media
|
91 |
+
3. Attach multiple files at once
|
92 |
+
4. Custom fields for each Attachment
|
93 |
+
5. Drag and drop to sort
|
94 |
|
95 |
== Changelog ==
|
96 |
|
97 |
+
= 3.0.6 =
|
98 |
+
* Fixed a possible JavaScript error if an Attachment that's an image doesn't have a proper thumbnail URL
|
99 |
+
* Added a total() method that will return the number of Attachments for the current instance
|
100 |
+
* When requesting the image() for a non-image Attachment, the WordPress-defined icon will be returned
|
101 |
+
* Added an icon() method that will return the WordPress-defined icon for the Attachment
|
102 |
+
* Cleaned up a PHP Warning when trying to save for an undefined field type
|
103 |
+
* Fixed an issue where template tags would be output for non-image Attachments after saving
|
104 |
+
|
105 |
+
= 3.0.5 =
|
106 |
+
* Fixed a regression in handling Custom Post Type names that would too aggressively interfere with instance regustration
|
107 |
+
* Fixed an issue when working with non-image Attachments
|
108 |
+
|
109 |
+
= 3.0.4 =
|
110 |
+
* Fixed an issue that prevented the choosing of a Featured Image for a Custom Post Type if Attachments was activated
|
111 |
+
* Attachments now only enqueues its assets on edit screens that actually utilize Attachments
|
112 |
+
* Fixed a potential JavaScript error triggered when a 'thumbnail' image size was not available
|
113 |
+
* Prevented incorrect usage of dashes used in CPT names for post_type argument when registering Attachments instances (fixes an integration issue with WP e-Commerce)
|
114 |
+
* Prevented re-running of migration process to avoid duplicates (e.g. on browser reload)
|
115 |
+
|
116 |
+
= 3.0.3 =
|
117 |
+
* Fixed an issue that prevented defining a post ID when retrieving Attachments outside The Loop
|
118 |
+
* Cleaned up potential PHP warning when Attachments were requested for a post that had none
|
119 |
+
|
120 |
+
= 3.0.2 =
|
121 |
+
* Fixed an issue where some HTML entities were not properly stored
|
122 |
+
|
123 |
+
= 3.0.1 =
|
124 |
+
* Fixed an issue where legacy mode was always enabled
|
125 |
+
|
126 |
+
= 3.0 =
|
127 |
+
* **Major** rewrite. After three years of development, Attachments has been rewritten to make
|
128 |
+
even better use of what WordPress has to offer
|
129 |
+
* Utilizes the brand spanking new 3.5 Media workflow
|
130 |
+
* Configuration now takes place within your theme or a plugin
|
131 |
+
* Multiple meta boxes! You can segment groups of Attachments with new instances, each unique
|
132 |
+
* Dynamic fields! You can manipulate which fields each instance uses
|
133 |
+
* File type limits. Limit which files are available to Attachments (e.g. images, audio, video)
|
134 |
+
|
135 |
= 1.6.2.1 =
|
136 |
* Fixed an issue with Handlebars in Firefox
|
137 |
* Better handling of Attachment name
|
263 |
|
264 |
== Upgrade Notice ==
|
265 |
|
266 |
+
= 3.0 =
|
267 |
+
**You will need to update your theme files that use Attachments 3.0**. Version 1.x of Attachments has been *fully deprecated* but is still available. If you would like to continue to use the (no longer supported) 1.x version you may add the following to your wp-config.php:
|
268 |
+
|
269 |
+
`define( 'ATTACHMENTS_LEGACY', true ); // force the legacy version of Attachments`
|
270 |
+
|
271 |
+
Version 3 is a *major* rewrite. While I've taken precautions in ensuring you won't lose any saved data it is important to back up your databse prior to upgrading in case something goes wrong. This version is a complete rewrite so all legacy data will be left in place, but a migration must take place to match the new data storage model and workflow.
|
272 |
+
|
273 |
= 1.0.8 =
|
274 |
As always, be sure to back up your database and files before upgrading.
|
275 |
|
280 |
|
281 |
Planned feature additions include:
|
282 |
|
283 |
+
* Additional field type: textarea
|
284 |
+
* Additional field type: WYSIWYG
|
285 |
+
* Additional field type: checkbox
|
286 |
+
* Additional field type: radio
|
287 |
+
* Additional field type: select
|
288 |
+
* User-defined limiting the number of Attachments per instance
|
289 |
+
* User-defined custom field types
|
290 |
+
* Additional hooks/actions from top to bottom
|
291 |
+
* Shortcode(s)
|
292 |
+
* Output templates
|
293 |
|
294 |
== Usage ==
|
295 |
|
296 |
+
When Attachments is first activated, a default instance is created titled Attachments. It has two fields:
|
297 |
|
298 |
+
1. Title
|
299 |
+
1. Caption
|
300 |
|
301 |
+
If you would like to *disable the default instance* (meta box titled 'Attachments' with a 'Title' and 'Caption' field) add the following to your `wp-config.php`:
|
302 |
|
303 |
+
`define( 'ATTACHMENTS_DEFAULT_INSTANCE', false );`
|
|
|
|
|
|
|
|
|
|
|
304 |
|
305 |
+
You may create instances with your own custom fields by using the `attachments_register` action. To create your own instance add the following to your theme's `functions.php` or your own plugin:
|
306 |
+
|
307 |
+
`<?php
|
308 |
+
function my_attachments( $attachments )
|
309 |
+
{
|
310 |
+
$args = array(
|
311 |
+
|
312 |
+
// title of the meta box (string)
|
313 |
+
'label' => 'My Attachments',
|
314 |
+
|
315 |
+
// all post types to utilize (string|array)
|
316 |
+
'post_type' => array( 'post', 'page' ),
|
317 |
+
|
318 |
+
// allowed file type(s) (array) (image|video|text|audio|application)
|
319 |
+
'filetype' => null, // no filetype limit
|
320 |
+
|
321 |
+
// include a note within the meta box (string)
|
322 |
+
'note' => 'Attach files here!',
|
323 |
+
|
324 |
+
// text for 'Attach' button (string)
|
325 |
+
'button_text' => __( 'Attach Files', 'attachments' ),
|
326 |
+
|
327 |
+
// text for modal 'Attach' button (string)
|
328 |
+
'modal_text' => __( 'Attach', 'attachments' ),
|
329 |
+
|
330 |
+
// fields for this instance (array)
|
331 |
+
'fields' => array(
|
332 |
+
array(
|
333 |
+
'name' => 'title', // unique field name
|
334 |
+
'type' => 'text', // registered field type (field available in 3.0: text)
|
335 |
+
'label' => __( 'Title', 'attachments' ), // label to display
|
336 |
+
),
|
337 |
+
array(
|
338 |
+
'name' => 'caption', // unique field name
|
339 |
+
'type' => 'text', // registered field type (field available in 3.0: text)
|
340 |
+
'label' => __( 'Caption', 'attachments' ), // label to display
|
341 |
+
),
|
342 |
+
array(
|
343 |
+
'name' => 'copyright', // unique field name
|
344 |
+
'type' => 'text', // registered field type (field available in 3.0: text)
|
345 |
+
'label' => __( 'Copyright', 'attachments' ), // label to display
|
346 |
+
),
|
347 |
+
),
|
348 |
+
|
349 |
+
);
|
350 |
+
|
351 |
+
$attachments->register( 'my_attachments', $args ); // unique instance name
|
352 |
+
}
|
353 |
+
|
354 |
+
add_action( 'attachments_register', 'my_attachments' );`
|
355 |
+
|
356 |
+
Once your instances are set up and working, you'll also need to edit your theme's template files to pull the data to the front end. To retrieve the Attachments for the current post, add this within The Loop:
|
357 |
+
|
358 |
+
`<?php $attachments = new Attachments( 'attachments' ); /* pass the instance name */ ?>
|
359 |
+
<?php if( $attachments->exist() ) : ?>
|
360 |
+
<h3>Attachments</h3>
|
361 |
+
<ul>
|
362 |
+
<?php while( $attachment = $attachments->get() ) : ?>
|
363 |
+
<li>
|
364 |
+
<pre><?php print_r( $attachment ); ?></pre>
|
365 |
+
</li>
|
366 |
+
<?php endwhile; ?>
|
367 |
+
</ul>
|
368 |
+
<?php endif; ?>`
|
369 |
+
|
370 |
+
If you want to get the Attachments for a post **outside The Loop**, add a second parameter with the post ID when instantiating Attachments:
|
371 |
|
372 |
`<?php
|
373 |
+
// retrieve all Attachments for the 'attachments' instance of post 123
|
374 |
+
$attachments = new Attachments( 'attachments', 123 );
|
375 |
+
?>
|
376 |
+
<?php if( $attachments->exist() ) : ?>
|
377 |
+
<h3>Attachments</h3>
|
378 |
+
<ul>
|
379 |
+
<?php while( $attachment = $attachments->get() ) : ?>
|
380 |
+
<li>
|
381 |
+
<pre><?php print_r( $attachment ); ?></pre>
|
382 |
+
</li>
|
383 |
+
<?php endwhile; ?>
|
384 |
+
</ul>
|
385 |
+
<?php endif; ?>`
|
386 |
+
|
387 |
+
You can also retrieve various attributes of the current Attachment using these utility functions:
|
388 |
+
|
389 |
+
`<?php $attachments = new Attachments( 'attachments' ); /* pass the instance name */ ?>
|
390 |
+
<?php if( $attachments->exist() ) : ?>
|
391 |
+
<h3>Attachments</h3>
|
392 |
+
<p>Total Attachments: <?php echo $attachments->total(); ?></p>
|
393 |
+
<ul>
|
394 |
+
<?php while( $attachments->get() ) : ?>
|
395 |
+
<li>
|
396 |
+
ID: <?php echo $attachments->id(); ?><br />
|
397 |
+
Type: <?php echo $attachments->type(); ?><br />
|
398 |
+
Subtype: <?php echo $attachments->subtype(); ?><br />
|
399 |
+
URL: <?php echo $attachments->url(); ?><br />
|
400 |
+
Image: <?php echo $attachments->image( 'thumbnail' ); ?><br />
|
401 |
+
Source: <?php echo $attachments->src( 'full' ); ?><br />
|
402 |
+
Size: <?php echo $attachments->filesize(); ?><br />
|
403 |
+
Title Field: <?php echo $attachments->field( 'title' ); ?><br />
|
404 |
+
Caption Field: <?php echo $attachments->field( 'caption' ); ?>
|
405 |
+
</li>
|
406 |
+
<?php endwhile; ?>
|
407 |
+
</ul>
|
408 |
+
<?php endif; ?>`
|
screenshot-1.jpg
DELETED
Binary file
|
screenshot-2.jpg
DELETED
Binary file
|
screenshot-3.jpg
DELETED
Binary file
|
upgrade.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// nothing yet
|
views/index.php
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
<?php
|
views/options.php
ADDED
@@ -0,0 +1,274 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if( !defined( 'ABSPATH' ) ) exit;
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Migrate Attachments 1.x records to 3.0's format
|
8 |
+
*
|
9 |
+
* @since 3.0
|
10 |
+
*/
|
11 |
+
function attachments_migrate( $instance = null, $title = null, $caption = null )
|
12 |
+
{
|
13 |
+
// sanitize
|
14 |
+
if( is_null( $instance ) || empty( $instance ) || is_null( $title ) || is_null( $caption ) )
|
15 |
+
return false;
|
16 |
+
|
17 |
+
$instance = str_replace( '-', '_', sanitize_title( $instance ) );
|
18 |
+
$title = empty( $title ) ? false : str_replace( '-', '_', sanitize_title( $title ) );
|
19 |
+
$caption = empty( $caption ) ? false : str_replace( '-', '_', sanitize_title( $caption ) );
|
20 |
+
|
21 |
+
// we need our deprecated functions
|
22 |
+
include_once( ATTACHMENTS_DIR . '/deprecated/get-attachments.php' );
|
23 |
+
|
24 |
+
// grab all of the posts we need to migrate
|
25 |
+
$query = new WP_Query( 'post_type=any&post_status=any&posts_per_page=-1&meta_key=_attachments' );
|
26 |
+
|
27 |
+
$count = 0;
|
28 |
+
|
29 |
+
// loop through each post
|
30 |
+
while( $query->have_posts() )
|
31 |
+
{
|
32 |
+
// set up postdata
|
33 |
+
$query->the_post();
|
34 |
+
|
35 |
+
// let's first decode our Attachments data
|
36 |
+
$existing_attachments = get_post_meta( $query->post->ID, '_attachments', false );
|
37 |
+
|
38 |
+
$post_attachments = array();
|
39 |
+
|
40 |
+
// check to make sure we've got data
|
41 |
+
if( is_array( $existing_attachments ) && count( $existing_attachments ) > 0 )
|
42 |
+
{
|
43 |
+
// loop through each existing attachment
|
44 |
+
foreach( $existing_attachments as $attachment )
|
45 |
+
{
|
46 |
+
// decode and unserialize the data
|
47 |
+
$data = unserialize( base64_decode( $attachment ) );
|
48 |
+
|
49 |
+
array_push( $post_attachments, array(
|
50 |
+
'id' => stripslashes( $data['id'] ),
|
51 |
+
'title' => stripslashes( $data['title'] ),
|
52 |
+
'caption' => stripslashes( $data['caption'] ),
|
53 |
+
'order' => stripslashes( $data['order'] )
|
54 |
+
));
|
55 |
+
}
|
56 |
+
|
57 |
+
// sort attachments
|
58 |
+
if( count( $post_attachments ) > 1 )
|
59 |
+
{
|
60 |
+
usort( $post_attachments, 'attachments_cmp' );
|
61 |
+
}
|
62 |
+
}
|
63 |
+
|
64 |
+
// we have our Attachments entries
|
65 |
+
|
66 |
+
// let's check to see if we're migrating after population has taken place
|
67 |
+
$existing_attachments = get_post_meta( $query->post->ID, 'attachments', false );
|
68 |
+
|
69 |
+
if( !isset( $existing_attachments[0] ) )
|
70 |
+
$existing_attachments[0] = '';
|
71 |
+
|
72 |
+
$existing_attachments = json_decode( $existing_attachments[0] );
|
73 |
+
|
74 |
+
if( !is_object( $existing_attachments ) )
|
75 |
+
$existing_attachments = new stdClass();
|
76 |
+
|
77 |
+
// we'll loop through the legacy Attachments and save them in the new format
|
78 |
+
foreach( $post_attachments as $legacy_attachment )
|
79 |
+
{
|
80 |
+
// convert to the new format
|
81 |
+
$converted_attachment = array( 'id' => $legacy_attachment['id'] );
|
82 |
+
|
83 |
+
// fields are technically optional so we'll add those separately
|
84 |
+
// we're also going to encode them in the same way the main class does
|
85 |
+
if( $title )
|
86 |
+
$converted_attachment['fields'][$title] = htmlentities( stripslashes( $legacy_attachment['title'] ), ENT_QUOTES );
|
87 |
+
|
88 |
+
if( $caption )
|
89 |
+
$converted_attachment['fields'][$caption] = htmlentities( stripslashes( $legacy_attachment['caption'] ), ENT_QUOTES );
|
90 |
+
|
91 |
+
// check to see if the existing Attachments have our target instance
|
92 |
+
if( !isset( $existing_attachments->$instance ) )
|
93 |
+
{
|
94 |
+
// the instance doesn't exist so we need to create it
|
95 |
+
$existing_attachments->$instance = array();
|
96 |
+
}
|
97 |
+
|
98 |
+
// we need to convert our array to an object
|
99 |
+
$converted_attachment['fields'] = (object) $converted_attachment['fields'];
|
100 |
+
$converted_attachment = (object) $converted_attachment;
|
101 |
+
|
102 |
+
// append this legacy attachment to the existing instance
|
103 |
+
array_push( $existing_attachments->$instance, $converted_attachment );
|
104 |
+
}
|
105 |
+
|
106 |
+
// we're done! let's save everything in our new format
|
107 |
+
$existing_attachments = json_encode( $existing_attachments );
|
108 |
+
|
109 |
+
// save it to the database
|
110 |
+
update_post_meta( $query->post->ID, 'attachments', $existing_attachments );
|
111 |
+
|
112 |
+
// increment our counter
|
113 |
+
$count++;
|
114 |
+
}
|
115 |
+
|
116 |
+
return $count;
|
117 |
+
}
|
118 |
+
|
119 |
+
if( isset( $_GET['dismiss'] ) )
|
120 |
+
{
|
121 |
+
if( !wp_verify_nonce( $_GET['nonce'], 'attachments-dismiss') ) wp_die( __( 'Invalid request', 'attachments' ) );
|
122 |
+
|
123 |
+
add_option( 'attachments_ignore_migration', true, '', 'no' );
|
124 |
+
}
|
125 |
+
?>
|
126 |
+
|
127 |
+
<div class="wrap">
|
128 |
+
|
129 |
+
<div id="icon-options-general" class="icon32"><br /></div>
|
130 |
+
|
131 |
+
<h2><?php _e( 'Attachments', 'attachments' ); ?></h2>
|
132 |
+
|
133 |
+
<?php if( isset( $_GET['overview'] ) ) : ?>
|
134 |
+
|
135 |
+
<div class="message updated" id="message">
|
136 |
+
<p><?php _e( "<strong>Attachments has changed significantly since it's last update.</strong> These changes <em>will affect your themes and plugins</em>.", 'attachments' ); ?></p>
|
137 |
+
</div>
|
138 |
+
|
139 |
+
<h4><?php _e( 'Immediate Reversal to Attachments 1.x', 'attachments' ); ?></h4>
|
140 |
+
|
141 |
+
<p><?php _e( 'If you would like to immediately <em>revert to the old version of Attachments</em> you may do so by downgrading the plugin install itself, or adding the following to your', 'attachments' ); ?> <code>wp-config.php</code>:</p>
|
142 |
+
|
143 |
+
<pre><code>define( 'ATTACHMENTS_LEGACY', true );</code></pre>
|
144 |
+
|
145 |
+
<h2><?php _e( 'Overview of changes from Attachments 1.x', 'attachments' ); ?></h2>
|
146 |
+
|
147 |
+
<p><?php _e( "A lot has changed since Attachments 1.x. The entire codebase was rewritten to not only make better use of the stellar Media updates in WordPress 3.5, but to also facilitate some exciting features coming down the line. With this rewrite came significant changes to the way you will work with Attachments. One of the biggest changes in Attachments 3.0 is the ability to create multiple meta boxes of Attachments, each with any number of custom fields you define. By default, Attachments will re-implement the meta box you've been using until now, but <strong>you will need to trigger a migration to the new format</strong>.", 'attachments' ); ?></p>
|
148 |
+
|
149 |
+
<h3><?php _e( 'Migrating Attachments 1.x data to Attachments 3.x', 'attachments' ); ?></h3>
|
150 |
+
|
151 |
+
<p><?php _e( "If you have existing Attachments 1.x data and are using it, a migration script has been bundled here and you can use it below. If you would like to directly migrate from Attachments 1.x to Attachments 3.x you can use the defaults put in place and your data will be migrated to the new format quickly and easily. Alternatively, if you'd like to customize the fields you're using a bit, you can do that first and then adjust the migration parameters to map the old fields to your new ones.", 'attachments' ); ?></p>
|
152 |
+
|
153 |
+
<h3><?php _e( 'Setting up Instances', 'attachments' ); ?></h3>
|
154 |
+
|
155 |
+
<p><?php _e( 'Attachments 3.0 ships with what are called <em>instances</em>. An instance is equivalent to a meta box on an edit screen and it has a number of properties you can customize. Please read the README for more information.', 'attachments' ); ?> <a href="https://github.com/jchristopher/attachments/blob/master/README.md#usage"><?php _e( 'Additinoal instructions', 'attachments' ); ?>.</a></p>
|
156 |
+
|
157 |
+
<h3><?php _e( 'Retrieving Attachments in your theme', 'attachments' ); ?></h3>
|
158 |
+
|
159 |
+
<p><?php _e( 'As always has been the case with Attachments, editing your theme files is required. The syntax to do so has changed in Attachments 3.0. Please read the', 'attachments' ); ?> <a href="https://github.com/jchristopher/attachments/blob/master/README.md#usage"><?php _e( 'Additinoal instructions', 'attachments' ); ?></a>.</p>
|
160 |
+
|
161 |
+
<form action="options-general.php" method="get">
|
162 |
+
<input type="hidden" name="page" value="attachments" />
|
163 |
+
<input type="hidden" name="dismiss" value="1" />
|
164 |
+
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce( 'attachments-dismiss' ); ?>" />
|
165 |
+
|
166 |
+
<p class="submit">
|
167 |
+
<input type="submit" name="submit" id="submit" class="button button-secondary" value="<?php esc_attr_e( 'Dismiss these notices without migrating', 'attachments' ); ?>" />
|
168 |
+
</p>
|
169 |
+
</form>
|
170 |
+
|
171 |
+
<?php endif; ?>
|
172 |
+
|
173 |
+
<?php
|
174 |
+
|
175 |
+
// check for any legacy Attachments
|
176 |
+
$legacy = new WP_Query( 'post_type=any&post_status=any&posts_per_page=1&meta_key=_attachments' );
|
177 |
+
|
178 |
+
// check to see if we're migrating
|
179 |
+
if( isset( $_GET['migrate'] ) )
|
180 |
+
{
|
181 |
+
switch( intval( $_GET['migrate'] ) )
|
182 |
+
{
|
183 |
+
case 1:
|
184 |
+
if( !wp_verify_nonce( $_GET['nonce'], 'attachments-migrate-1') ) wp_die( __( 'Invalid request', 'attachments' ) );
|
185 |
+
?>
|
186 |
+
<h3><?php _e( 'Migration Step 1', 'attachments' ); ?></h3>
|
187 |
+
<p><?php _e( "In order to migrate Attachments 1.x data, you need to set which instance and fields in version 3.0+ you'd like to use:", 'attachments' ); ?></p>
|
188 |
+
<form action="options-general.php" method="get">
|
189 |
+
<input type="hidden" name="page" value="attachments" />
|
190 |
+
<input type="hidden" name="migrate" value="2" />
|
191 |
+
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce( 'attachments-migrate-2' ); ?>" />
|
192 |
+
<table class="form-table">
|
193 |
+
<tbody>
|
194 |
+
<tr valign="top">
|
195 |
+
<th scope="row">
|
196 |
+
<label for="attachments-instance"><?php _e( 'Attachments 3.x Instance', 'attachments' ); ?></label>
|
197 |
+
</th>
|
198 |
+
<td>
|
199 |
+
<input name="attachments-instance" id="attachments-instance" value="attachments" class="regular-text" />
|
200 |
+
<p class="description"><?php _e( 'The instance name you would like to use in the migration. Required.', 'attachments' ); ?></p>
|
201 |
+
</td>
|
202 |
+
</tr>
|
203 |
+
<tr valign="top">
|
204 |
+
<th scope="row">
|
205 |
+
<label for="attachments-title"><?php _e( 'Attachments 3.x Title', 'attachments' ); ?></label>
|
206 |
+
</th>
|
207 |
+
<td>
|
208 |
+
<input name="attachments-title" id="attachments-title" value="title" class="regular-text" />
|
209 |
+
<p class="description"><?php _e( 'The <code>Title</code> field data will be migrated to this field name in Attachments 3.x. Leave empty to disregard.', 'attachments' ); ?></p>
|
210 |
+
</td>
|
211 |
+
</tr>
|
212 |
+
<tr valign="top">
|
213 |
+
<th scope="row">
|
214 |
+
<label for="attachments-caption"><?php _e( 'Attachments 3.x Caption', 'attachments' ); ?></label>
|
215 |
+
</th>
|
216 |
+
<td>
|
217 |
+
<input name="attachments-caption" id="attachments-caption" value="caption" class="regular-text" />
|
218 |
+
<p class="description"><?php _e( 'The <code>Caption</code> field data will be migrated to this field name in Attachments 3.x. Leave empty to disregard.', 'attachments' ); ?></p>
|
219 |
+
</td>
|
220 |
+
</tr>
|
221 |
+
</tbody>
|
222 |
+
</table>
|
223 |
+
<p class="submit">
|
224 |
+
<input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_attr_e( 'Start Migration', 'attachments' ); ?>" />
|
225 |
+
</p>
|
226 |
+
</form>
|
227 |
+
<?php
|
228 |
+
break;
|
229 |
+
|
230 |
+
case 2:
|
231 |
+
if( !wp_verify_nonce( $_GET['nonce'], 'attachments-migrate-2') ) wp_die( __( 'Invalid request', 'attachments' ) );
|
232 |
+
|
233 |
+
$total = attachments_migrate( $_GET['attachments-instance'], $_GET['attachments-title'], $_GET['attachments-caption'] );
|
234 |
+
|
235 |
+
if( false == get_option( 'attachments_migrated' ) ) :
|
236 |
+
?>
|
237 |
+
<h3><?php _e( 'Migration Complete!', 'attachments' ); ?></h3>
|
238 |
+
<p><?php _e( 'The migration has completed.', 'attachments' ); ?> <strong><?php _e( 'Migrated', 'attachments'); ?>: <?php echo $total; ?></strong>.</p>
|
239 |
+
<?php else : ?>
|
240 |
+
<h3><?php _e( 'Migration Already Run!', 'attachments' ); ?></h3>
|
241 |
+
<p><?php _e( 'The migration has already been run. The migration process has not been repeated.', 'attachments' ); ?></p>
|
242 |
+
<?php endif;
|
243 |
+
|
244 |
+
// make sure the database knows the migration has run
|
245 |
+
add_option( 'attachments_migrated', true, '', 'no' );
|
246 |
+
|
247 |
+
break;
|
248 |
+
}
|
249 |
+
}
|
250 |
+
else
|
251 |
+
{ ?>
|
252 |
+
<?php if( false == get_option( 'attachments_migrated' ) && $legacy->found_posts ) : ?>
|
253 |
+
<h2><?php _e( 'Migrate legacy Attachments', 'attachments' ); ?></h2>
|
254 |
+
<p><?php _e( 'Attachments has found records from version 1.x. Would you like to migrate them to version 3?', 'attachments' ); ?></p>
|
255 |
+
<p><a href="?page=attachments&migrate=1&nonce=<?php echo wp_create_nonce( 'attachments-migrate-1' ); ?>" class="button-primary button"><?php _e( 'Migrate legacy Attachments', 'attachments' ); ?></a></p>
|
256 |
+
<?php elseif( true == get_option( 'attachments_migrated' ) ) : ?>
|
257 |
+
<p><?php _e( 'You have already migrated your legacy Attachments.', 'attachments' ); ?></p>
|
258 |
+
<?php endif; ?>
|
259 |
+
<h2><?php _e( 'Revert to version 1.x', 'attachments' ); ?></h2>
|
260 |
+
<p><?php _e( 'If you would like to forcefully revert to the 1.x version branch of Attachments, add the following to your', 'attachments' ); ?> <code>wp-config.php</code>:</p>
|
261 |
+
<p><code>define( 'ATTACHMENTS_LEGACY', true );</code></p>
|
262 |
+
<h2><?php _e( 'Meta box customization', 'attachments' ); ?></h2>
|
263 |
+
<p><?php _e( 'By default, Attachments implements a single meta box on Posts and Pages with two fields. You can disable this default instance by adding the following to your', 'attachments' ); ?> <code>wp-config.php</code>:</p>
|
264 |
+
<p><code>define( 'ATTACHMENTS_DEFAULT_INSTANCE', false );</code></p>
|
265 |
+
<p><?php _e( "Your Attachments meta box(es) can be customized by adding the following to your theme's", 'attachments' ); ?> <code>functions.php</code>:</p>
|
266 |
+
<script src="https://gist.github.com/4217475.js"> </script>
|
267 |
+
<h2><?php _e( 'Using Attachments data in your theme', 'attachments' ); ?></h2>
|
268 |
+
<p><?php _e( "Attachments does not directly integrate with your theme out of the box, you will need to edit your theme's template files where appropriate. You can add the following within The Loop to retrieve all Attachments data for the current post:", 'attachments' ); ?></p>
|
269 |
+
<script src="https://gist.github.com/4217483.js"> </script>
|
270 |
+
<?php }
|
271 |
+
|
272 |
+
?>
|
273 |
+
|
274 |
+
</div>
|