Version Description
- Fixed an issue resulting in a black image, when image was cropped without moving the crop handles
Download this release
Release Info
Developer | andersthorborg |
Plugin | Advanced Custom Fields: Image Crop Add-on |
Version | 0.8 |
Comparing to | |
See all releases |
Version 0.8
- acf-image-crop.php +76 -0
- assets/screenshot-1.png +0 -0
- assets/screenshot-2.png +0 -0
- assets/screenshot-3.png +0 -0
- assets/screenshot-4.png +0 -0
- assets/screenshot-5.png +0 -0
- assets/screenshot-6.png +0 -0
- css/input.css +63 -0
- css/options.css +6 -0
- image_crop-v3.php +352 -0
- image_crop-v4.php +553 -0
- js/input.js +218 -0
- js/options.js +17 -0
- readme.txt +73 -0
acf-image-crop.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Advanced Custom Fields: Image Crop Add-on
|
4 |
+
Plugin URI: https://github.com/andersthorborg/ACF-Image-Crop
|
5 |
+
Description: An image field making it possible/required for the user to crop the selected image to the specified image size or dimensions
|
6 |
+
Version: 0.8
|
7 |
+
Author: Anders Thorborg
|
8 |
+
Author URI: http://thorb.org
|
9 |
+
License: GPLv2 or later
|
10 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
11 |
+
*/
|
12 |
+
|
13 |
+
|
14 |
+
class acf_field_image_crop_plugin
|
15 |
+
{
|
16 |
+
/*
|
17 |
+
* Construct
|
18 |
+
*
|
19 |
+
* @description:
|
20 |
+
* @since: 3.6
|
21 |
+
* @created: 1/04/13
|
22 |
+
*/
|
23 |
+
|
24 |
+
function __construct()
|
25 |
+
{
|
26 |
+
// set text domain
|
27 |
+
/*
|
28 |
+
$domain = 'acf-image_crop';
|
29 |
+
$mofile = trailingslashit(dirname(__File__)) . 'lang/' . $domain . '-' . get_locale() . '.mo';
|
30 |
+
load_textdomain( $domain, $mofile );
|
31 |
+
*/
|
32 |
+
|
33 |
+
|
34 |
+
// version 4+
|
35 |
+
add_action('acf/register_fields', array($this, 'register_fields'));
|
36 |
+
|
37 |
+
|
38 |
+
// version 3-
|
39 |
+
add_action('init', array( $this, 'init' ), 5);
|
40 |
+
}
|
41 |
+
|
42 |
+
|
43 |
+
/*
|
44 |
+
* Init
|
45 |
+
*
|
46 |
+
* @description:
|
47 |
+
* @since: 3.6
|
48 |
+
* @created: 1/04/13
|
49 |
+
*/
|
50 |
+
|
51 |
+
function init()
|
52 |
+
{
|
53 |
+
if(function_exists('register_field'))
|
54 |
+
{
|
55 |
+
register_field('acf_field_image_crop', dirname(__File__) . '/image_crop-v3.php');
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
/*
|
60 |
+
* register_fields
|
61 |
+
*
|
62 |
+
* @description:
|
63 |
+
* @since: 3.6
|
64 |
+
* @created: 1/04/13
|
65 |
+
*/
|
66 |
+
|
67 |
+
function register_fields()
|
68 |
+
{
|
69 |
+
include_once('image_crop-v4.php');
|
70 |
+
}
|
71 |
+
|
72 |
+
}
|
73 |
+
|
74 |
+
new acf_field_image_crop_plugin();
|
75 |
+
|
76 |
+
?>
|
assets/screenshot-1.png
ADDED
Binary file
|
assets/screenshot-2.png
ADDED
Binary file
|
assets/screenshot-3.png
ADDED
Binary file
|
assets/screenshot-4.png
ADDED
Binary file
|
assets/screenshot-5.png
ADDED
Binary file
|
assets/screenshot-6.png
ADDED
Binary file
|
css/input.css
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.field_type-image_crop .crop-stage .crop-image{
|
2 |
+
max-width:100%;
|
3 |
+
}
|
4 |
+
.field_type-image_crop .crop-stage .crop-action{
|
5 |
+
float:left;
|
6 |
+
width:65%;
|
7 |
+
}
|
8 |
+
.field_type-image_crop .crop-stage .crop-preview{
|
9 |
+
float:right;
|
10 |
+
width:25%;
|
11 |
+
}
|
12 |
+
.field_type-image_crop .crop-stage .crop-preview .preview{
|
13 |
+
width:100%;
|
14 |
+
}
|
15 |
+
|
16 |
+
.field_type-image_crop .crop-stage .crop-preview .crop-controls{
|
17 |
+
padding-top:20px;
|
18 |
+
clear: both;
|
19 |
+
}
|
20 |
+
|
21 |
+
.field_type-image_crop .crop-section .crop-stage, .field_type-image_crop.cropping .image-section, .field_type-image_crop.cropping .init-crop-button{
|
22 |
+
display:none;
|
23 |
+
}
|
24 |
+
.field_type-image_crop.cropping .crop-stage {
|
25 |
+
display:block;
|
26 |
+
position:fixed;
|
27 |
+
top:60px;
|
28 |
+
width:800px;
|
29 |
+
left:50%;
|
30 |
+
margin-left:-440px;
|
31 |
+
height:auto;
|
32 |
+
background-color: #fff;
|
33 |
+
box-shadow: 0px 0px 3px rgba(0,0,0,0.5);
|
34 |
+
padding:40px;
|
35 |
+
z-index: 100;
|
36 |
+
|
37 |
+
}
|
38 |
+
.field_type-image_crop.cropping .has-image, .field_type-image_crop.cropping .crop-section{
|
39 |
+
width:100%;
|
40 |
+
}
|
41 |
+
|
42 |
+
.field_type-image_crop .crop-stage.loading .crop-controls{
|
43 |
+
-webkit-transition: opacity 300ms;
|
44 |
+
-moz-transition: opacity 300ms;
|
45 |
+
-ms-transition: opacity 300ms;
|
46 |
+
-o-transition: opacity 300ms;
|
47 |
+
transition: opacity 300ms;
|
48 |
+
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
|
49 |
+
filter: alpha(opacity=20);
|
50 |
+
opacity:0.2;
|
51 |
+
}
|
52 |
+
|
53 |
+
.button.init-crop-button{
|
54 |
+
margin-top: 20px;
|
55 |
+
}
|
56 |
+
#acf-image-crop-overlay{
|
57 |
+
position:fixed;
|
58 |
+
top:0px;
|
59 |
+
left:0px;
|
60 |
+
right:0px;
|
61 |
+
bottom:0px;
|
62 |
+
background-color: rgba(0,0,0,0.8);
|
63 |
+
}
|
css/options.css
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.field_type-image_crop .dimensions-wrap .acf-input-wrap{
|
2 |
+
float:left;
|
3 |
+
}
|
4 |
+
.field_type-image_crop .dimensions-wrap .dimension{
|
5 |
+
width:150px;
|
6 |
+
}
|
image_crop-v3.php
ADDED
@@ -0,0 +1,352 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class acf_field_image_crop extends acf_Field
|
4 |
+
{
|
5 |
+
|
6 |
+
// vars
|
7 |
+
var $settings, // will hold info such as dir / path
|
8 |
+
$defaults; // will hold default field options
|
9 |
+
|
10 |
+
|
11 |
+
/*--------------------------------------------------------------------------------------
|
12 |
+
*
|
13 |
+
* Constructor
|
14 |
+
* - This function is called when the field class is initalized on each page.
|
15 |
+
* - Here you can add filters / actions and setup any other functionality for your field
|
16 |
+
*
|
17 |
+
* @author Elliot Condon
|
18 |
+
* @since 2.2.0
|
19 |
+
*
|
20 |
+
*-------------------------------------------------------------------------------------*/
|
21 |
+
|
22 |
+
function __construct($parent)
|
23 |
+
{
|
24 |
+
|
25 |
+
// do not delete!
|
26 |
+
parent::__construct($parent);
|
27 |
+
|
28 |
+
// set name / title
|
29 |
+
$this->name = 'image_crop';
|
30 |
+
$this->title = __('Image - Custom crop');
|
31 |
+
$this->defaults = array(
|
32 |
+
// add default here to merge into your field.
|
33 |
+
// This makes life easy when creating the field options as you don't need to use any if( isset('') ) logic. eg:
|
34 |
+
//'preview_size' => 'thumbnail'
|
35 |
+
);
|
36 |
+
|
37 |
+
// settings
|
38 |
+
$this->settings = array(
|
39 |
+
'path' => $this->helpers_get_path(__FILE__),
|
40 |
+
'dir' => $this->helpers_get_dir(__FILE__),
|
41 |
+
'version' => '1.0.0'
|
42 |
+
);
|
43 |
+
|
44 |
+
}
|
45 |
+
|
46 |
+
|
47 |
+
/*
|
48 |
+
* helpers_get_path
|
49 |
+
*
|
50 |
+
* @description: calculates the path (works for plugin / theme folders)
|
51 |
+
* @since: 3.6
|
52 |
+
* @created: 30/01/13
|
53 |
+
*/
|
54 |
+
|
55 |
+
function helpers_get_path($file)
|
56 |
+
{
|
57 |
+
return trailingslashit(dirname($file));
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
/*
|
62 |
+
* helpers_get_dir
|
63 |
+
*
|
64 |
+
* @description: calculates the directory (works for plugin / theme folders)
|
65 |
+
* @since: 3.6
|
66 |
+
* @created: 30/01/13
|
67 |
+
*/
|
68 |
+
|
69 |
+
function helpers_get_dir($file)
|
70 |
+
{
|
71 |
+
$dir = trailingslashit(dirname($file));
|
72 |
+
$count = 0;
|
73 |
+
|
74 |
+
|
75 |
+
// sanitize for Win32 installs
|
76 |
+
$dir = str_replace('\\', '/', $dir);
|
77 |
+
|
78 |
+
|
79 |
+
// if file is in plugins folder
|
80 |
+
$wp_plugin_dir = str_replace('\\', '/', WP_PLUGIN_DIR);
|
81 |
+
$dir = str_replace($wp_plugin_dir, WP_PLUGIN_URL, $dir, $count);
|
82 |
+
|
83 |
+
|
84 |
+
if($count < 1)
|
85 |
+
{
|
86 |
+
// if file is in wp-content folder
|
87 |
+
$wp_content_dir = str_replace('\\', '/', WP_CONTENT_DIR);
|
88 |
+
$dir = str_replace($wp_content_dir, WP_CONTENT_URL, $dir, $count);
|
89 |
+
}
|
90 |
+
|
91 |
+
|
92 |
+
if($count < 1)
|
93 |
+
{
|
94 |
+
// if file is in ??? folder
|
95 |
+
$wp_dir = str_replace('\\', '/', ABSPATH);
|
96 |
+
$dir = str_replace($wp_dir, site_url('/'), $dir);
|
97 |
+
}
|
98 |
+
|
99 |
+
return $dir;
|
100 |
+
}
|
101 |
+
|
102 |
+
|
103 |
+
/*--------------------------------------------------------------------------------------
|
104 |
+
*
|
105 |
+
* create_options
|
106 |
+
* - this function is called from core/field_meta_box.php to create extra options
|
107 |
+
* for your field
|
108 |
+
*
|
109 |
+
* @params
|
110 |
+
* - $key (int) - the $_POST obejct key required to save the options to the field
|
111 |
+
* - $field (array) - the field object
|
112 |
+
*
|
113 |
+
* @author Elliot Condon
|
114 |
+
* @since 2.2.0
|
115 |
+
*
|
116 |
+
*-------------------------------------------------------------------------------------*/
|
117 |
+
|
118 |
+
function create_options($key, $field)
|
119 |
+
{
|
120 |
+
// defaults?
|
121 |
+
/*
|
122 |
+
$field = array_merge($this->defaults, $field);
|
123 |
+
*/
|
124 |
+
|
125 |
+
|
126 |
+
// Create Field Options HTML
|
127 |
+
?>
|
128 |
+
<tr class="field_option field_option_<?php echo $this->name; ?>">
|
129 |
+
<td class="label">
|
130 |
+
<label><?php _e("Preview Size", 'acf'); ?></label>
|
131 |
+
<p class="description"><?php _e("Thumbnail is advised", 'acf'); ?></p>
|
132 |
+
</td>
|
133 |
+
<td>
|
134 |
+
<?php
|
135 |
+
|
136 |
+
$this->parent->create_field(array(
|
137 |
+
'type' => 'radio',
|
138 |
+
'name' => 'fields[' . $key . '][preview_size]',
|
139 |
+
'value' => $field['preview_size'],
|
140 |
+
'layout' => 'horizontal',
|
141 |
+
'choices' => array(
|
142 |
+
'thumbnail' => __('Thumbnail'),
|
143 |
+
'something_else' => __('Something Else'),
|
144 |
+
)
|
145 |
+
));
|
146 |
+
|
147 |
+
?>
|
148 |
+
</td>
|
149 |
+
</tr>
|
150 |
+
<?php
|
151 |
+
}
|
152 |
+
|
153 |
+
|
154 |
+
/*--------------------------------------------------------------------------------------
|
155 |
+
*
|
156 |
+
* pre_save_field
|
157 |
+
* - this function is called when saving your acf object. Here you can manipulate the
|
158 |
+
* field object and it's options before it gets saved to the database.
|
159 |
+
*
|
160 |
+
* @author Elliot Condon
|
161 |
+
* @since 2.2.0
|
162 |
+
*
|
163 |
+
*-------------------------------------------------------------------------------------*/
|
164 |
+
|
165 |
+
function pre_save_field($field)
|
166 |
+
{
|
167 |
+
// Note: This function can be removed if not used
|
168 |
+
|
169 |
+
// do stuff with field (mostly format options data)
|
170 |
+
|
171 |
+
return parent::pre_save_field($field);
|
172 |
+
}
|
173 |
+
|
174 |
+
|
175 |
+
/*--------------------------------------------------------------------------------------
|
176 |
+
*
|
177 |
+
* create_field
|
178 |
+
* - this function is called on edit screens to produce the html for this field
|
179 |
+
*
|
180 |
+
* @author Elliot Condon
|
181 |
+
* @since 2.2.0
|
182 |
+
*
|
183 |
+
*-------------------------------------------------------------------------------------*/
|
184 |
+
|
185 |
+
function create_field($field)
|
186 |
+
{
|
187 |
+
// defaults?
|
188 |
+
/*
|
189 |
+
$field = array_merge($this->defaults, $field);
|
190 |
+
*/
|
191 |
+
|
192 |
+
// perhaps use $field['preview_size'] to alter the markup?
|
193 |
+
|
194 |
+
|
195 |
+
// create Field HTML
|
196 |
+
?>
|
197 |
+
<div>
|
198 |
+
|
199 |
+
</div>
|
200 |
+
<?php
|
201 |
+
}
|
202 |
+
|
203 |
+
|
204 |
+
/*--------------------------------------------------------------------------------------
|
205 |
+
*
|
206 |
+
* admin_head
|
207 |
+
* - this function is called in the admin_head of the edit screen where your field
|
208 |
+
* is created. Use this function to create css and javascript to assist your
|
209 |
+
* create_field() function.
|
210 |
+
*
|
211 |
+
* @author Elliot Condon
|
212 |
+
* @since 2.2.0
|
213 |
+
*
|
214 |
+
*-------------------------------------------------------------------------------------*/
|
215 |
+
|
216 |
+
function admin_head()
|
217 |
+
{
|
218 |
+
// Note: This function can be removed if not used
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
+
/*--------------------------------------------------------------------------------------
|
223 |
+
*
|
224 |
+
* admin_print_scripts / admin_print_styles
|
225 |
+
* - this function is called in the admin_print_scripts / admin_print_styles where
|
226 |
+
* your field is created. Use this function to register css and javascript to assist
|
227 |
+
* your create_field() function.
|
228 |
+
*
|
229 |
+
* @author Elliot Condon
|
230 |
+
* @since 3.0.0
|
231 |
+
*
|
232 |
+
*-------------------------------------------------------------------------------------*/
|
233 |
+
|
234 |
+
function admin_print_scripts()
|
235 |
+
{
|
236 |
+
// Note: This function can be removed if not used
|
237 |
+
|
238 |
+
|
239 |
+
// register acf scripts
|
240 |
+
wp_register_script('acf-input-image_crop', $this->settings['dir'] . 'js/input.js', array('acf-input'), $this->settings['version']);
|
241 |
+
|
242 |
+
// scripts
|
243 |
+
wp_enqueue_script(array(
|
244 |
+
'acf-input-image_crop',
|
245 |
+
));
|
246 |
+
|
247 |
+
|
248 |
+
}
|
249 |
+
|
250 |
+
function admin_print_styles()
|
251 |
+
{
|
252 |
+
// Note: This function can be removed if not used
|
253 |
+
|
254 |
+
|
255 |
+
wp_register_style('acf-input-image_crop', $this->settings['dir'] . 'css/input.css', array('acf-input'), $this->settings['version']);
|
256 |
+
|
257 |
+
// styles
|
258 |
+
wp_enqueue_style(array(
|
259 |
+
'acf-input-image_crop',
|
260 |
+
));
|
261 |
+
}
|
262 |
+
|
263 |
+
|
264 |
+
/*--------------------------------------------------------------------------------------
|
265 |
+
*
|
266 |
+
* update_value
|
267 |
+
* - this function is called when saving a post object that your field is assigned to.
|
268 |
+
* the function will pass through the 3 parameters for you to use.
|
269 |
+
*
|
270 |
+
* @params
|
271 |
+
* - $post_id (int) - usefull if you need to save extra data or manipulate the current
|
272 |
+
* post object
|
273 |
+
* - $field (array) - usefull if you need to manipulate the $value based on a field option
|
274 |
+
* - $value (mixed) - the new value of your field.
|
275 |
+
*
|
276 |
+
* @author Elliot Condon
|
277 |
+
* @since 2.2.0
|
278 |
+
*
|
279 |
+
*-------------------------------------------------------------------------------------*/
|
280 |
+
|
281 |
+
function update_value($post_id, $field, $value)
|
282 |
+
{
|
283 |
+
// Note: This function can be removed if not used
|
284 |
+
|
285 |
+
// do stuff with value
|
286 |
+
|
287 |
+
// save value
|
288 |
+
parent::update_value($post_id, $field, $value);
|
289 |
+
}
|
290 |
+
|
291 |
+
|
292 |
+
/*--------------------------------------------------------------------------------------
|
293 |
+
*
|
294 |
+
* get_value
|
295 |
+
* - called from the edit page to get the value of your field. This function is useful
|
296 |
+
* if your field needs to collect extra data for your create_field() function.
|
297 |
+
*
|
298 |
+
* @params
|
299 |
+
* - $post_id (int) - the post ID which your value is attached to
|
300 |
+
* - $field (array) - the field object.
|
301 |
+
*
|
302 |
+
* @author Elliot Condon
|
303 |
+
* @since 2.2.0
|
304 |
+
*
|
305 |
+
*-------------------------------------------------------------------------------------*/
|
306 |
+
|
307 |
+
function get_value($post_id, $field)
|
308 |
+
{
|
309 |
+
// Note: This function can be removed if not used
|
310 |
+
|
311 |
+
// get value
|
312 |
+
$value = parent::get_value($post_id, $field);
|
313 |
+
|
314 |
+
// format value
|
315 |
+
|
316 |
+
// return value
|
317 |
+
return $value;
|
318 |
+
}
|
319 |
+
|
320 |
+
|
321 |
+
/*--------------------------------------------------------------------------------------
|
322 |
+
*
|
323 |
+
* get_value_for_api
|
324 |
+
* - called from your template file when using the API functions (get_field, etc).
|
325 |
+
* This function is useful if your field needs to format the returned value
|
326 |
+
*
|
327 |
+
* @params
|
328 |
+
* - $post_id (int) - the post ID which your value is attached to
|
329 |
+
* - $field (array) - the field object.
|
330 |
+
*
|
331 |
+
* @author Elliot Condon
|
332 |
+
* @since 3.0.0
|
333 |
+
*
|
334 |
+
*-------------------------------------------------------------------------------------*/
|
335 |
+
|
336 |
+
function get_value_for_api($post_id, $field)
|
337 |
+
{
|
338 |
+
// Note: This function can be removed if not used
|
339 |
+
|
340 |
+
// get value
|
341 |
+
$value = $this->get_value($post_id, $field);
|
342 |
+
|
343 |
+
// format value
|
344 |
+
|
345 |
+
// return value
|
346 |
+
return $value;
|
347 |
+
|
348 |
+
}
|
349 |
+
|
350 |
+
}
|
351 |
+
|
352 |
+
?>
|
image_crop-v4.php
ADDED
@@ -0,0 +1,553 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class acf_field_image_crop extends acf_field_image
|
4 |
+
{
|
5 |
+
// vars
|
6 |
+
var $settings, // will hold info such as dir / path
|
7 |
+
$defaults; // will hold default field options
|
8 |
+
|
9 |
+
|
10 |
+
/*
|
11 |
+
* __construct
|
12 |
+
*
|
13 |
+
* Set name / label needed for actions / filters
|
14 |
+
*
|
15 |
+
* @since 3.6
|
16 |
+
* @date 23/01/13
|
17 |
+
*/
|
18 |
+
|
19 |
+
function __construct()
|
20 |
+
{
|
21 |
+
// vars
|
22 |
+
$this->name = 'image_crop';
|
23 |
+
$this->label = __('Image with user-crop');
|
24 |
+
$this->category = __("Content",'acf'); // Basic, Content, Choice, etc
|
25 |
+
$this->defaults = array(
|
26 |
+
'force_crop' => 'no',
|
27 |
+
'crop_type' => 'hard',
|
28 |
+
'preview_size' => 'medium',
|
29 |
+
'save_format' => 'object',
|
30 |
+
'target_size' => 'thumbnail'
|
31 |
+
// add default here to merge into your field.
|
32 |
+
// This makes life easy when creating the field options as you don't need to use any if( isset('') ) logic. eg:
|
33 |
+
//'preview_size' => 'thumbnail'
|
34 |
+
);
|
35 |
+
|
36 |
+
//Call grandparent cunstructor
|
37 |
+
acf_field::__construct();
|
38 |
+
|
39 |
+
// settings
|
40 |
+
$this->settings = array(
|
41 |
+
'path' => apply_filters('acf/helpers/get_path', __FILE__),
|
42 |
+
'dir' => apply_filters('acf/helpers/get_dir', __FILE__),
|
43 |
+
'version' => '1.0.0'
|
44 |
+
);
|
45 |
+
|
46 |
+
// add ajax action to be able to retrieve full image size via javascript
|
47 |
+
add_action( 'wp_ajax_acf_image_crop_get_image_size', array( &$this, 'crop_get_image_size' ) );
|
48 |
+
add_action( 'wp_ajax_acf_image_crop_perform_crop', array( &$this, 'perform_crop' ) );
|
49 |
+
|
50 |
+
}
|
51 |
+
|
52 |
+
// AJAX handler for retieving full image dimensions from ID
|
53 |
+
public function crop_get_image_size()
|
54 |
+
{
|
55 |
+
$img = wp_get_attachment_image_src( $_POST['image_id'], 'full');
|
56 |
+
if($img){
|
57 |
+
echo json_encode( array(
|
58 |
+
'url' => $img[0],
|
59 |
+
'width' => $img[1],
|
60 |
+
'height' => $img[2]
|
61 |
+
) );
|
62 |
+
}
|
63 |
+
exit;
|
64 |
+
}
|
65 |
+
|
66 |
+
|
67 |
+
/*
|
68 |
+
* create_options()
|
69 |
+
*
|
70 |
+
* Create extra options for your field. This is rendered when editing a field.
|
71 |
+
* The value of $field['name'] can be used (like bellow) to save extra data to the $field
|
72 |
+
*
|
73 |
+
* @type action
|
74 |
+
* @since 3.6
|
75 |
+
* @date 23/01/13
|
76 |
+
*
|
77 |
+
* @param $field - an array holding all the field's data
|
78 |
+
*/
|
79 |
+
|
80 |
+
function create_options($field)
|
81 |
+
{
|
82 |
+
// defaults?
|
83 |
+
/*
|
84 |
+
$field = array_merge($this->defaults, $field);
|
85 |
+
*/
|
86 |
+
|
87 |
+
// key is needed in the field names to correctly save the data
|
88 |
+
$key = $field['name'];
|
89 |
+
|
90 |
+
|
91 |
+
// Create Field Options HTML
|
92 |
+
?>
|
93 |
+
<tr class="field_option field_option_<?php echo $this->name; ?>">
|
94 |
+
<td class="label">
|
95 |
+
<label><?php _e("Return Value",'acf'); ?></label>
|
96 |
+
<p><?php _e("Specify the returned value on front end",'acf') ?></p>
|
97 |
+
</td>
|
98 |
+
<td>
|
99 |
+
<?php
|
100 |
+
do_action('acf/create_field', array(
|
101 |
+
'type' => 'radio',
|
102 |
+
'name' => 'fields['.$key.'][save_format]',
|
103 |
+
'value' => $field['save_format'],
|
104 |
+
'layout' => 'horizontal',
|
105 |
+
'choices' => array(
|
106 |
+
'object' => __("Image Object",'acf'),
|
107 |
+
'url' => __("Image URL",'acf'),
|
108 |
+
'id' => __("Image ID",'acf')
|
109 |
+
)
|
110 |
+
));
|
111 |
+
?>
|
112 |
+
</td>
|
113 |
+
</tr>
|
114 |
+
<tr class="field_option field_option_<?php echo $this->name; ?>">
|
115 |
+
<td class="label">
|
116 |
+
<label><?php _e("Crop type", 'acf'); ?></label>
|
117 |
+
<p class="description"><?php _e("Select the type of crop the user should perform", 'acf'); ?></p>
|
118 |
+
</td>
|
119 |
+
<td>
|
120 |
+
<?php
|
121 |
+
|
122 |
+
do_action('acf/create_field', array(
|
123 |
+
'type' => 'select',
|
124 |
+
'name' => 'fields[' . $key . '][crop_type]',
|
125 |
+
'value' => $field['target_size'],
|
126 |
+
'class' => 'crop-type-select',
|
127 |
+
'choices' => array(
|
128 |
+
'hard' => __('Hard crop', 'acf'),
|
129 |
+
'min' => __('Minimal dimensions', 'acf')
|
130 |
+
)
|
131 |
+
));
|
132 |
+
|
133 |
+
?>
|
134 |
+
</td>
|
135 |
+
</tr>
|
136 |
+
<tr class="field_option field_option_<?php echo $this->name; ?>">
|
137 |
+
<td class="label">
|
138 |
+
<label><?php _e("Target Size", 'acf'); ?></label>
|
139 |
+
<p class="description"><?php _e("Select the target size for this field", 'acf'); ?></p>
|
140 |
+
</td>
|
141 |
+
<td>
|
142 |
+
<?php
|
143 |
+
$sizes = array_merge(apply_filters('acf/get_image_sizes', array()), array('custom' => __("Custom size",'acf')));
|
144 |
+
unset($sizes['full']);
|
145 |
+
do_action('acf/create_field', array(
|
146 |
+
'type' => 'select',
|
147 |
+
'name' => 'fields[' . $key . '][target_size]',
|
148 |
+
'value' => $field['target_size'],
|
149 |
+
'class' => 'target-size-select',
|
150 |
+
'choices' => $sizes
|
151 |
+
));
|
152 |
+
|
153 |
+
?>
|
154 |
+
</td>
|
155 |
+
</tr>
|
156 |
+
<tr class="field_option field_option_<?php echo $this->name; ?> dimensions-wrap <?php echo ($field['target_size'] == 'custom' ? '' : 'hidden') ?>">
|
157 |
+
<td class="label">
|
158 |
+
<label><?php _e("Dimensions", 'acf'); ?></label>
|
159 |
+
<p class="description"><span class="dimensions-description <?php echo ($field['crop_type'] != 'hard' ? 'hidden' : '') ?>" data-type="hard"><?php _e("Enter the dimensions for the image.", 'acf'); ?></span><span class="dimensions-description <?php echo ($field['crop_type'] != 'min' ? 'hidden' : '') ?>" data-type="min"><?php _e("Enter the minimum dimensions for the image. Leave fields blank for no minimum requirement.", 'acf'); ?></span></p>
|
160 |
+
</td>
|
161 |
+
<td>
|
162 |
+
<?php
|
163 |
+
|
164 |
+
do_action('acf/create_field', array(
|
165 |
+
'type' => 'text',
|
166 |
+
'name' => 'fields[' . $key . '][width]',
|
167 |
+
'value' => $field['width'],
|
168 |
+
'class' => 'width dimension',
|
169 |
+
'placeholder' => 'Width'
|
170 |
+
));
|
171 |
+
?>
|
172 |
+
<div class="acf-input-wrap"> : </div>
|
173 |
+
<?php
|
174 |
+
do_action('acf/create_field', array(
|
175 |
+
'type' => 'text',
|
176 |
+
'name' => 'fields[' . $key . '][height]',
|
177 |
+
'value' => $field['height'],
|
178 |
+
'class' => 'height dimension',
|
179 |
+
'placeholder' => 'Height'
|
180 |
+
));
|
181 |
+
?>
|
182 |
+
</td>
|
183 |
+
</tr>
|
184 |
+
<tr class="field_option field_option_<?php echo $this->name; ?>">
|
185 |
+
<td class="label">
|
186 |
+
<label><?php _e("Force crop",'acf'); ?></label>
|
187 |
+
<p><?php _e("Force the user to crop the image as soon at it is selected.",'acf') ?></p>
|
188 |
+
</td>
|
189 |
+
<td>
|
190 |
+
<?php
|
191 |
+
do_action('acf/create_field', array(
|
192 |
+
'type' => 'radio',
|
193 |
+
'name' => 'fields['.$key.'][force_crop]',
|
194 |
+
'value' => $field['force_crop'],
|
195 |
+
'layout' => 'horizontal',
|
196 |
+
'choices' => array(
|
197 |
+
'yes' => __("Yes",'acf'),
|
198 |
+
'no' => __("No",'acf')
|
199 |
+
)
|
200 |
+
));
|
201 |
+
?>
|
202 |
+
</td>
|
203 |
+
</tr>
|
204 |
+
<tr class="field_option field_option_<?php echo $this->name; ?>">
|
205 |
+
<td class="label">
|
206 |
+
<label><?php _e("Preview Size", 'acf'); ?></label>
|
207 |
+
<p class="description"><?php _e("Select the target size for this field", 'acf'); ?></p>
|
208 |
+
</td>
|
209 |
+
<td>
|
210 |
+
<?php
|
211 |
+
do_action('acf/create_field', array(
|
212 |
+
'type' => 'select',
|
213 |
+
'name' => 'fields[' . $key . '][preview_size]',
|
214 |
+
'value' => $field['preview_size'],
|
215 |
+
'class' => 'preview-size-select',
|
216 |
+
'choices' => apply_filters('acf/get_image_sizes', array())
|
217 |
+
));
|
218 |
+
|
219 |
+
?>
|
220 |
+
</td>
|
221 |
+
</tr>
|
222 |
+
|
223 |
+
<?php
|
224 |
+
|
225 |
+
}
|
226 |
+
|
227 |
+
|
228 |
+
/*
|
229 |
+
* create_field()
|
230 |
+
*
|
231 |
+
* Create the HTML interface for your field
|
232 |
+
*
|
233 |
+
* @param $field - an array holding all the field's data
|
234 |
+
*
|
235 |
+
* @type action
|
236 |
+
* @since 3.6
|
237 |
+
* @date 23/01/13
|
238 |
+
*/
|
239 |
+
|
240 |
+
function create_field( $field )
|
241 |
+
{
|
242 |
+
// defaults?
|
243 |
+
/*
|
244 |
+
$field = array_merge($this->defaults, $field);
|
245 |
+
*/
|
246 |
+
|
247 |
+
// perhaps use $field['preview_size'] to alter the markup?
|
248 |
+
$data = json_decode($field['value']);
|
249 |
+
// create Field HTML
|
250 |
+
// vars
|
251 |
+
$o = array(
|
252 |
+
'class' => '',
|
253 |
+
'url' => '',
|
254 |
+
);
|
255 |
+
$originalImage = null;
|
256 |
+
if( $data && is_object($data) && is_numeric($data->original_image) )
|
257 |
+
{
|
258 |
+
$originalImage = wp_get_attachment_image_src($data->original_image, 'full');
|
259 |
+
$url = wp_get_attachment_image_src($data->original_image, $field['preview_size']);
|
260 |
+
if(is_numeric($data->cropped_image)){
|
261 |
+
$url = wp_get_attachment_image_src($data->cropped_image, $field['preview_size']);
|
262 |
+
}
|
263 |
+
$o['class'] = 'active';
|
264 |
+
$o['url'] = $url[0];
|
265 |
+
}
|
266 |
+
$width = 0;
|
267 |
+
$height = 0;
|
268 |
+
if($field['target_size'] == 'custom'){
|
269 |
+
$width = $field['width'];
|
270 |
+
$height = $field['height'];
|
271 |
+
}
|
272 |
+
else{
|
273 |
+
global $_wp_additional_image_sizes;
|
274 |
+
$s = $field['target_size'];
|
275 |
+
if (isset($_wp_additional_image_sizes[$s])) {
|
276 |
+
$width = intval($_wp_additional_image_sizes[$s]['width']);
|
277 |
+
$height = intval($_wp_additional_image_sizes[$s]['height']);
|
278 |
+
} else {
|
279 |
+
$width = get_option($s.'_size_w');
|
280 |
+
$height = get_option($s.'_size_h');
|
281 |
+
}
|
282 |
+
}
|
283 |
+
?>
|
284 |
+
<div class="acf-image-uploader clearfix <?php echo $o['class']; ?>" data-preview_size="<?php echo $field['preview_size']; ?>" data-library="<?php echo $field['library']; ?>" data-width="<?php echo $width ?>" data-height="<?php echo $height ?>" data-crop-type="<?php echo $field['crop_type'] ?>" <?php echo ($field['force_crop'] == 'yes' ? 'data-force-crop="true"' : '') ?> >
|
285 |
+
<input class="acf-image-value" data-original-image="<?php echo $data->original_image ?>" data-cropped-image="<?php echo $data->cropped_image ?>" type="hidden" name="<?php echo $field['name']; ?>" value="<?php echo htmlspecialchars($field['value']); ?>" />
|
286 |
+
<div class="has-image">
|
287 |
+
<div class="image-section">
|
288 |
+
<div class="hover">
|
289 |
+
<ul class="bl">
|
290 |
+
<li><a class="acf-button-delete ir" href="#"><?php _e("Remove",'acf'); ?></a></li>
|
291 |
+
<li><a class="acf-button-edit ir" href="#"><?php _e("Edit",'acf'); ?></a></li>
|
292 |
+
</ul>
|
293 |
+
</div>
|
294 |
+
<img class="acf-image-image" src="<?php echo $o['url']; ?>" alt=""/>
|
295 |
+
</div>
|
296 |
+
<div class="crop-section">
|
297 |
+
<div class="crop-stage">
|
298 |
+
<div class="crop-action">
|
299 |
+
<h4>Crop the image</h4>
|
300 |
+
<?php if ($originalImage ): ?>
|
301 |
+
<img class="crop-image" src="<?php echo $originalImage[0] ?>" data-width="<?php echo $originalImage[1] ?>" data-height="<?php echo $originalImage[2] ?>" alt="">
|
302 |
+
<?php endif ?>
|
303 |
+
</div>
|
304 |
+
<div class="crop-preview">
|
305 |
+
<h4>Preview</h4>
|
306 |
+
<div class="preview"></div>
|
307 |
+
<div class="crop-controls">
|
308 |
+
<a href="#" class="button button-large cancel-crop-button">Cancel</a> <a href="#" class="button button-large button-primary perform-crop-button">Crop!</a>
|
309 |
+
</div>
|
310 |
+
</div>
|
311 |
+
<!-- <img src="<?php echo $o['url']; ?>" alt=""/> -->
|
312 |
+
</div>
|
313 |
+
<a href="#" class="button button-large init-crop-button">Crop</a>
|
314 |
+
</div>
|
315 |
+
</div>
|
316 |
+
<div class="no-image">
|
317 |
+
<p><?php _e('No image selected','acf'); ?> <input type="button" class="button add-image" value="<?php _e('Add Image','acf'); ?>" />
|
318 |
+
</div>
|
319 |
+
</div>
|
320 |
+
<?php
|
321 |
+
}
|
322 |
+
|
323 |
+
|
324 |
+
|
325 |
+
/*
|
326 |
+
* format_value_for_api()
|
327 |
+
*
|
328 |
+
* This filter is appied to the $value after it is loaded from the db and before it is passed back to the api functions such as the_field
|
329 |
+
*
|
330 |
+
* @type filter
|
331 |
+
* @since 3.6
|
332 |
+
* @date 23/01/13
|
333 |
+
*
|
334 |
+
* @param $value - the value which was loaded from the database
|
335 |
+
* @param $post_id - the $post_id from which the value was loaded
|
336 |
+
* @param $field - the field array holding all the field options
|
337 |
+
*
|
338 |
+
* @return $value - the modified value
|
339 |
+
*/
|
340 |
+
|
341 |
+
function format_value_for_api( $value, $post_id, $field )
|
342 |
+
{
|
343 |
+
|
344 |
+
// validate
|
345 |
+
if( !$value )
|
346 |
+
{
|
347 |
+
return false;
|
348 |
+
}
|
349 |
+
$data = json_decode($value);
|
350 |
+
if(!is_object($data)){
|
351 |
+
return $value;
|
352 |
+
}
|
353 |
+
|
354 |
+
$value = $data->cropped_image;
|
355 |
+
|
356 |
+
// format
|
357 |
+
if( $field['save_format'] == 'url' )
|
358 |
+
{
|
359 |
+
$value = wp_get_attachment_url( $data->cropped_image );
|
360 |
+
}
|
361 |
+
elseif( $field['save_format'] == 'object' )
|
362 |
+
{
|
363 |
+
$attachment = get_post( $data->cropped_image );
|
364 |
+
|
365 |
+
|
366 |
+
// validate
|
367 |
+
if( !$attachment )
|
368 |
+
{
|
369 |
+
return false;
|
370 |
+
}
|
371 |
+
|
372 |
+
|
373 |
+
// create array to hold value data
|
374 |
+
$src = wp_get_attachment_image_src( $attachment->ID, 'full' );
|
375 |
+
|
376 |
+
$value = array(
|
377 |
+
'id' => $attachment->ID,
|
378 |
+
'alt' => get_post_meta($attachment->ID, '_wp_attachment_image_alt', true),
|
379 |
+
'title' => $attachment->post_title,
|
380 |
+
'caption' => $attachment->post_excerpt,
|
381 |
+
'description' => $attachment->post_content,
|
382 |
+
'mime_type' => $attachment->post_mime_type,
|
383 |
+
'url' => $src[0],
|
384 |
+
'width' => $src[1],
|
385 |
+
'height' => $src[2],
|
386 |
+
'sizes' => array(),
|
387 |
+
);
|
388 |
+
|
389 |
+
|
390 |
+
// find all image sizes
|
391 |
+
$image_sizes = get_intermediate_image_sizes();
|
392 |
+
|
393 |
+
if( $image_sizes )
|
394 |
+
{
|
395 |
+
foreach( $image_sizes as $image_size )
|
396 |
+
{
|
397 |
+
// find src
|
398 |
+
$src = wp_get_attachment_image_src( $attachment->ID, $image_size );
|
399 |
+
|
400 |
+
// add src
|
401 |
+
$value[ 'sizes' ][ $image_size ] = $src[0];
|
402 |
+
$value[ 'sizes' ][ $image_size . '-width' ] = $src[1];
|
403 |
+
$value[ 'sizes' ][ $image_size . '-height' ] = $src[2];
|
404 |
+
}
|
405 |
+
// foreach( $image_sizes as $image_size )
|
406 |
+
}
|
407 |
+
// if( $image_sizes )
|
408 |
+
|
409 |
+
}
|
410 |
+
return $value;
|
411 |
+
|
412 |
+
}
|
413 |
+
|
414 |
+
/*
|
415 |
+
* input_admin_enqueue_scripts()
|
416 |
+
*
|
417 |
+
* This action is called in the admin_enqueue_scripts action on the edit screen where your field is created.
|
418 |
+
* Use this action to add css + javascript to assist your create_field() action.
|
419 |
+
*
|
420 |
+
* $info http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts
|
421 |
+
* @type action
|
422 |
+
* @since 3.6
|
423 |
+
* @date 23/01/13
|
424 |
+
*/
|
425 |
+
|
426 |
+
function input_admin_enqueue_scripts()
|
427 |
+
{
|
428 |
+
// Note: This function can be removed if not used
|
429 |
+
|
430 |
+
|
431 |
+
// register acf scripts
|
432 |
+
wp_register_script('acf-input-image_crop', $this->settings['dir'] . 'js/input.js', array('acf-input', 'imgareaselect'), $this->settings['version']);
|
433 |
+
|
434 |
+
wp_register_style('acf-input-image_crop', $this->settings['dir'] . 'css/input.css', array('acf-input'), $this->settings['version']);
|
435 |
+
wp_register_script( 'jcrop', includes_url( 'js/jcrop/jquery.Jcrop.min.css' ));
|
436 |
+
|
437 |
+
|
438 |
+
// scripts
|
439 |
+
wp_enqueue_script(array(
|
440 |
+
'acf-input-image_crop'
|
441 |
+
));
|
442 |
+
|
443 |
+
wp_localize_script( 'acf-input-image_crop', 'ajax', array('nonce' => wp_create_nonce('acf_nonce')) );
|
444 |
+
|
445 |
+
// styles
|
446 |
+
wp_enqueue_style(array(
|
447 |
+
'acf-input-image_crop',
|
448 |
+
'imgareaselect'
|
449 |
+
));
|
450 |
+
|
451 |
+
}
|
452 |
+
|
453 |
+
|
454 |
+
/*
|
455 |
+
* field_group_admin_enqueue_scripts()
|
456 |
+
*
|
457 |
+
* This action is called in the admin_enqueue_scripts action on the edit screen where your field is edited.
|
458 |
+
* Use this action to add css + javascript to assist your create_field_options() action.
|
459 |
+
*
|
460 |
+
* $info http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts
|
461 |
+
* @type action
|
462 |
+
* @since 3.6
|
463 |
+
* @date 23/01/13
|
464 |
+
*/
|
465 |
+
|
466 |
+
function field_group_admin_enqueue_scripts()
|
467 |
+
{
|
468 |
+
// Note: This function can be removed if not used
|
469 |
+
wp_register_script('acf-input-image-crop-options', $this->settings['dir'] . 'js/options.js', array('jquery'), $this->settings['version']);
|
470 |
+
wp_enqueue_script( 'acf-input-image-crop-options');
|
471 |
+
|
472 |
+
wp_register_style('acf-input-image-crop-options', $this->settings['dir'] . 'css/options.css');
|
473 |
+
wp_enqueue_style( 'acf-input-image-crop-options');
|
474 |
+
}
|
475 |
+
|
476 |
+
|
477 |
+
/*
|
478 |
+
* update_value()
|
479 |
+
*
|
480 |
+
* This filter is appied to the $value before it is updated in the db
|
481 |
+
*
|
482 |
+
* @type filter
|
483 |
+
* @since 3.6
|
484 |
+
* @date 23/01/13
|
485 |
+
*
|
486 |
+
* @param $value - the value which will be saved in the database
|
487 |
+
* @param $post_id - the $post_id of which the value will be saved
|
488 |
+
* @param $field - the field array holding all the field options
|
489 |
+
*
|
490 |
+
* @return $value - the modified value
|
491 |
+
*/
|
492 |
+
|
493 |
+
function update_value( $value, $post_id, $field )
|
494 |
+
{
|
495 |
+
// array?
|
496 |
+
if( is_array($value) && isset($value['id']) )
|
497 |
+
{
|
498 |
+
$value = $value['id'];
|
499 |
+
}
|
500 |
+
|
501 |
+
// object?
|
502 |
+
if( is_object($value) && isset($value->ID) )
|
503 |
+
{
|
504 |
+
$value = $value->ID;
|
505 |
+
}
|
506 |
+
|
507 |
+
return $value;
|
508 |
+
}
|
509 |
+
|
510 |
+
function perform_crop(){
|
511 |
+
$targetWidth = $_POST['target_width'];
|
512 |
+
$targetHeight = $_POST['target_height'];
|
513 |
+
$id = $this->generate_cropped_image($_POST['id'], $_POST['x1'], $_POST['x2'], $_POST['y1'], $_POST['y2'], $targetWidth, $targetHeight);
|
514 |
+
$previewUrl = wp_get_attachment_image_src( $id, $_POST['preview_size']);
|
515 |
+
$fullUrl = wp_get_attachment_image_src( $id, 'full');
|
516 |
+
$data = array(
|
517 |
+
'id' => $id,
|
518 |
+
'url_preview' => $previewUrl[0],
|
519 |
+
'url_full' => $fullUrl[0]
|
520 |
+
);
|
521 |
+
echo json_encode($data);
|
522 |
+
die();
|
523 |
+
}
|
524 |
+
|
525 |
+
function generate_cropped_image($id, $x1, $x2, $y1, $y2, $targetW, $targetH){//$id, $x1, $x2, $y$, $y2, $targetW, $targetH){
|
526 |
+
require_once ABSPATH . "/wp-admin/includes/file.php";
|
527 |
+
require_once ABSPATH . "/wp-admin/includes/image.php";
|
528 |
+
|
529 |
+
$filename = wp_crop_image($id, $x1, $y1, $x2 - $x1, $y2 - $y1, $targetW, $targetH);
|
530 |
+
// GENERATE NEW ATTACHMENT FROM NEW FILE
|
531 |
+
$wp_filetype = wp_check_filetype(basename($filename), null );
|
532 |
+
$attachment = array(
|
533 |
+
'guid' => $filename,
|
534 |
+
'post_mime_type' => $wp_filetype['type'],
|
535 |
+
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
|
536 |
+
'post_content' => '',
|
537 |
+
'post_status' => 'inherit'
|
538 |
+
);
|
539 |
+
$attach_id = wp_insert_attachment( $attachment, $filename);
|
540 |
+
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
|
541 |
+
wp_update_attachment_metadata( $attach_id, $attach_data );
|
542 |
+
|
543 |
+
// Return ID of cropped image
|
544 |
+
return $attach_id;
|
545 |
+
}
|
546 |
+
|
547 |
+
}
|
548 |
+
|
549 |
+
|
550 |
+
// create field
|
551 |
+
new acf_field_image_crop();
|
552 |
+
|
553 |
+
?>
|
js/input.js
ADDED
@@ -0,0 +1,218 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
(function($){
|
2 |
+
|
3 |
+
|
4 |
+
/*
|
5 |
+
* acf/setup_fields
|
6 |
+
*
|
7 |
+
* This event is triggered when ACF adds any new elements to the DOM.
|
8 |
+
*
|
9 |
+
* @type function
|
10 |
+
* @since 1.0.0
|
11 |
+
* @date 01/01/12
|
12 |
+
*
|
13 |
+
* @param event e: an event object. This can be ignored
|
14 |
+
* @param Element postbox: An element which contains the new HTML
|
15 |
+
*
|
16 |
+
* @return N/A
|
17 |
+
*/
|
18 |
+
|
19 |
+
$(document).on('acf/setup_fields', function(e, postbox){
|
20 |
+
$(postbox).find('.field_type-image_crop').each(function(){
|
21 |
+
var $field = $(this), $options = $field.find('.acf-image-uploader');
|
22 |
+
$field.find('.acf-image-value').on('change', function(){
|
23 |
+
var originalImage = $(this).val();
|
24 |
+
if($(this).val()){
|
25 |
+
$field.removeClass('invalid');
|
26 |
+
$field.find('.init-crop-button').removeAttr('disabled');
|
27 |
+
$field.find('.acf-image-value').data('original-image', originalImage);
|
28 |
+
$field.find('.acf-image-value').data('cropped-image', originalImage);
|
29 |
+
$field.find('.acf-image-value').data('cropped', false);
|
30 |
+
$.post(ajaxurl, {action: 'acf_image_crop_get_image_size', image_id: originalImage}, function(data, textStatus, xhr) {
|
31 |
+
if($field.find('img.crop-image').length == 0){
|
32 |
+
$field.find('.crop-action').append($('<img class="crop-image" src="#"/>'));
|
33 |
+
}
|
34 |
+
$field.find('img.crop-image').attr('src', data['url']);
|
35 |
+
$field.find('img.crop-image').data('width', data['width']);
|
36 |
+
$field.find('img.crop-image').data('height', data['height']);
|
37 |
+
var warnings = [];
|
38 |
+
var valid = true;
|
39 |
+
if($options.data('width') && data['width'] < $options.data('width')){
|
40 |
+
warnings.push('Width should be at least: ' + $options.data('width') + 'px (Selected image width: ' + data['width'] + 'px)');
|
41 |
+
valid = false;
|
42 |
+
}
|
43 |
+
if($options.data('height') && data['height'] < $options.data('height')){
|
44 |
+
warnings.push('Height should be at least: ' + $options.data('height') + 'px (Selected image height: ' + data['height'] + 'px)');
|
45 |
+
valid = false;
|
46 |
+
}
|
47 |
+
if(!valid){
|
48 |
+
$field.addClass('invalid');
|
49 |
+
$field.find('.init-crop-button').attr('disabled', 'disabled');
|
50 |
+
alert('Warning: The selected image is smaller than the required size:\n' + warnings.join('\n'));
|
51 |
+
}
|
52 |
+
else{
|
53 |
+
if($options.data('force-crop')){
|
54 |
+
initCrop($field);
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
}, 'json');
|
59 |
+
updateFieldValue($field);
|
60 |
+
}
|
61 |
+
else{
|
62 |
+
//Do nothing
|
63 |
+
}
|
64 |
+
|
65 |
+
})
|
66 |
+
$field.find('.init-crop-button').click(function(e){
|
67 |
+
e.preventDefault();
|
68 |
+
initCrop($field);
|
69 |
+
});
|
70 |
+
$field.find('.perform-crop-button').click(function(e){
|
71 |
+
e.preventDefault();
|
72 |
+
performCrop($field);
|
73 |
+
});
|
74 |
+
$field.find('.cancel-crop-button').click(function(e){
|
75 |
+
e.preventDefault();
|
76 |
+
cancelCrop($field);
|
77 |
+
});
|
78 |
+
});
|
79 |
+
|
80 |
+
});
|
81 |
+
|
82 |
+
function initCrop($field){
|
83 |
+
var $options = $field.find('.acf-image-uploader');
|
84 |
+
var options = {
|
85 |
+
handles: true,
|
86 |
+
onSelectEnd: function (img, selection) {
|
87 |
+
updateThumbnail($field, img, selection);
|
88 |
+
updateCropData($field, img, selection);
|
89 |
+
},
|
90 |
+
imageWidth:$options.find('.crop-stage img.crop-image').data('width'),
|
91 |
+
imageHeight:$options.find('.crop-stage img.crop-image').data('height'),
|
92 |
+
x1: 0,
|
93 |
+
y1: 0
|
94 |
+
};
|
95 |
+
if($options.data('crop-type') == 'hard'){
|
96 |
+
options.aspectRatio = $options.data('width') + ':' + $options.data('height');
|
97 |
+
options.minWidth = $options.data('width');
|
98 |
+
options.minHeight = $options.data('height');
|
99 |
+
options.x2 = $options.data('width');
|
100 |
+
options.y2 = $options.data('height');
|
101 |
+
}
|
102 |
+
else if($options.data('crop-type') == 'min'){
|
103 |
+
if($options.data('width')){
|
104 |
+
options.minWidth = $options.data('width');
|
105 |
+
options.x2 = $options.data('width');
|
106 |
+
}
|
107 |
+
else{
|
108 |
+
options.x2 = options.imageWidth;
|
109 |
+
}
|
110 |
+
if($options.data('height')){
|
111 |
+
options.minHeight = $options.data('height');
|
112 |
+
options.y2 = $options.data('height');
|
113 |
+
}
|
114 |
+
else{
|
115 |
+
options.y2 = options.imageHeight;
|
116 |
+
}
|
117 |
+
}
|
118 |
+
if(!$field.hasClass('invalid')){
|
119 |
+
toggleCropView($field);
|
120 |
+
$field.find('.crop-stage img.crop-image').imgAreaSelect(options);
|
121 |
+
updateCropData($field, $field.find('.crop-stage img.crop-image').get(0), {y1: options.y1, y2: options.y2, x1: options.x1, x2: options.x2});
|
122 |
+
updateThumbnail($field, $field.find('.crop-stage img.crop-image').get(0), {y1: options.y1, y2: options.y2, x1: options.x1, x2: options.x2});
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
function updateCropData($field, img, selection){
|
127 |
+
var $options = $field.find('.acf-image-uploader');
|
128 |
+
$options.data('x1', selection.x1);
|
129 |
+
$options.data('x2', selection.x2);
|
130 |
+
$options.data('y1', selection.y1);
|
131 |
+
$options.data('y2', selection.y2);
|
132 |
+
}
|
133 |
+
|
134 |
+
function updateThumbnail($field, img, selection){
|
135 |
+
var $options = $field.find('.acf-image-uploader');
|
136 |
+
var div = $field.find('.crop-preview .preview');
|
137 |
+
var targetWidth = $field.find('.crop-preview .preview').width();
|
138 |
+
var factor = targetWidth / (selection.x2 - selection.x1);
|
139 |
+
//image
|
140 |
+
div.css('background-image', 'url(' + img.src + ')');
|
141 |
+
//width
|
142 |
+
div.css('width', (selection.x2 - selection.x1) * factor);
|
143 |
+
//height
|
144 |
+
div.css('height', (selection.y2 - selection.y1) * factor);
|
145 |
+
//x offset
|
146 |
+
div.css('background-position-x', 0-(selection.x1 * factor));
|
147 |
+
//y offset
|
148 |
+
div.css('background-position-y', 0-(selection.y1 * factor));
|
149 |
+
div.css('background-size', $options.find('.crop-stage img.crop-image').data('width') * factor + 'px' + ' ' + $options.find('.crop-stage img.crop-image').data('height') * factor + 'px');
|
150 |
+
}
|
151 |
+
|
152 |
+
function generateCropJSON(originalImage, croppedImage){
|
153 |
+
var obj = {
|
154 |
+
original_image: originalImage,
|
155 |
+
cropped_image: croppedImage
|
156 |
+
}
|
157 |
+
return JSON.stringify(obj);
|
158 |
+
}
|
159 |
+
|
160 |
+
function performCrop($field){
|
161 |
+
if(!$field.find('.crop-stage').hasClass('loading')){
|
162 |
+
$field.find('.crop-stage').addClass('loading');
|
163 |
+
var $options = $field.find('.acf-image-uploader');
|
164 |
+
var targetWidth = $options.data('width');
|
165 |
+
var targetHeight = $options.data('height');
|
166 |
+
if($options.data('crop-type') == 'min'){
|
167 |
+
targetWidth = $options.data('x2') - $options.data('x1');
|
168 |
+
targetHeight = $options.data('y2') - $options.data('y1');
|
169 |
+
}
|
170 |
+
var data = {
|
171 |
+
action: 'acf_image_crop_perform_crop',
|
172 |
+
id: $field.find('.acf-image-value').data('original-image'),
|
173 |
+
x1: $options.data('x1'),
|
174 |
+
x2: $options.data('x2'),
|
175 |
+
y1: $options.data('y1'),
|
176 |
+
y2: $options.data('y2'),
|
177 |
+
target_width: targetWidth,
|
178 |
+
target_height: targetHeight,
|
179 |
+
preview_size: $options.data('preview_size')
|
180 |
+
}
|
181 |
+
$.post(ajaxurl, data, function(data, textStatus, xhr) {
|
182 |
+
$field.find('.acf-image-image').attr('src', data.url_preview);
|
183 |
+
$field.find('.acf-image-value').data('cropped-image', data.id);
|
184 |
+
$field.find('.acf-image-value').data('cropped', true);
|
185 |
+
updateFieldValue($field);
|
186 |
+
$field.find('.crop-stage').removeClass('loading');
|
187 |
+
cancelCrop($field);
|
188 |
+
}, 'json');
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
function cancelCrop($field){
|
193 |
+
toggleCropView($field);
|
194 |
+
$field.find('.crop-stage img.crop-image').imgAreaSelect({remove:true});
|
195 |
+
}
|
196 |
+
|
197 |
+
function toggleCropView($field){
|
198 |
+
if($field.hasClass('cropping')){
|
199 |
+
$('#acf-image-crop-overlay').remove();
|
200 |
+
}
|
201 |
+
else{
|
202 |
+
$('body').append($('<div id="acf-image-crop-overlay"></div>'));
|
203 |
+
}
|
204 |
+
$field.toggleClass('cropping');
|
205 |
+
|
206 |
+
}
|
207 |
+
|
208 |
+
function updateFieldValue($field){
|
209 |
+
var $input = $field.find('.acf-image-value');
|
210 |
+
$input.val(generateCropJSON($input.data('original-image'), $input.data('cropped-image')));
|
211 |
+
}
|
212 |
+
|
213 |
+
function getFullImageUrl(id, callback){
|
214 |
+
$.post(ajaxurl, {images: []}, function(data, textStatus, xhr) {
|
215 |
+
}, 'json');
|
216 |
+
}
|
217 |
+
|
218 |
+
})(jQuery);
|
js/options.js
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(function($){
|
2 |
+
$(document).on('change', '.field_type-image_crop .target-size-select', function(e) {
|
3 |
+
if($(this).val() == 'custom'){
|
4 |
+
$(this).parents('.field_type-image_crop').find('.dimensions-wrap').removeClass('hidden');
|
5 |
+
}
|
6 |
+
else{
|
7 |
+
$(this).parents('.field_type-image_crop').find('.dimensions-wrap').addClass('hidden');
|
8 |
+
}
|
9 |
+
|
10 |
+
});
|
11 |
+
$(document).on('change', '.field_type-image_crop .crop-type-select', function(e) {
|
12 |
+
|
13 |
+
$(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description').addClass('hidden');
|
14 |
+
$(this).parents('.field_type-image_crop').find('.dimensions-wrap .dimensions-description[data-type=' + $(this).val() + ']').removeClass('hidden');
|
15 |
+
|
16 |
+
});
|
17 |
+
});
|
readme.txt
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Advanced Custom Fields: Image Crop Add-on ===
|
2 |
+
Contributors: andersthorborg
|
3 |
+
Tags: afc, advanced custom fields, image crop, image, crop
|
4 |
+
Requires at least: 3.5
|
5 |
+
Tested up to: 3.8.1
|
6 |
+
Stable tag: 0.8
|
7 |
+
License: GPLv2 or later
|
8 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
+
|
10 |
+
An image field making it possible/required for the user to crop the selected image to the specified image size or dimensions
|
11 |
+
|
12 |
+
== Description ==
|
13 |
+
|
14 |
+
ACF image crop is an extended version of the native Image-field in ACF.
|
15 |
+
The field gives the developer/administrator the option to predefine a size for the image, which the user is prompted to crop on the various edit screens. This solves the common issue of images being cropped inappropriately by the automated center-crop, that wordpress performs.
|
16 |
+
|
17 |
+
The plugin supports the defined image sizes as well as a custom option, enabling the developer to specify the dimensions from within the field edit screen.
|
18 |
+
|
19 |
+
The field can be configured to enforce a hard crop or a minimal-dimension-based crop. The hard crop will lock the aspect ratio of the crop where as the minimal-dimension-based crop will not allow the user to crop the image below the specified dimensions.
|
20 |
+
|
21 |
+
This plugin diverts from plugins like [Manual Image Crop](http://wordpress.org/plugins/manual-image-crop/) in that when the user crops an image, a new attachment is generated, so that the relevant crop only applies in the context it is edited. It also spares the user from dealing with the concept of various image sizes. (This does however have the potential of over-crowding the media-directory with differently cropped versions of images).
|
22 |
+
|
23 |
+
= Compatibility =
|
24 |
+
|
25 |
+
This add-on will work with:
|
26 |
+
|
27 |
+
* version 4 and up
|
28 |
+
|
29 |
+
== Installation ==
|
30 |
+
|
31 |
+
This add-on can be treated as both a WP plugin and a theme include.
|
32 |
+
|
33 |
+
= Plugin =
|
34 |
+
1. Copy the 'acf-image_crop' folder into your plugins folder
|
35 |
+
2. Activate the plugin via the Plugins admin page
|
36 |
+
|
37 |
+
= Include =
|
38 |
+
1. Copy the 'acf-image_crop' folder into your theme folder (can use sub folders). You can place the folder anywhere inside the 'wp-content' directory
|
39 |
+
2. Edit your functions.php file and add the code below (Make sure the path is correct to include the acf-image_crop.php file)
|
40 |
+
|
41 |
+
`
|
42 |
+
add_action('acf/register_fields', 'my_register_fields');
|
43 |
+
|
44 |
+
function my_register_fields()
|
45 |
+
{
|
46 |
+
include_once('acf-image-crop/acf-image-crop.php');
|
47 |
+
}
|
48 |
+
`
|
49 |
+
|
50 |
+
== Screenshots ==
|
51 |
+
|
52 |
+
1. Use a registered image size as the field target size
|
53 |
+
2. Or use custom dimensions on the fly
|
54 |
+
3. On the edit screen, select/upload an image as usual
|
55 |
+
4. A crop-button will appear beneath the image (If desired, use the "Force user crop"-option to initialize the crop as soon as the user selects the image)
|
56 |
+
5. The image is cropped to the desired format, using the restrictions set under field options
|
57 |
+
6. The new format is shown using the specified preview size. The original image is kept with the field, so the image can be re-cropped at any time.
|
58 |
+
|
59 |
+
|
60 |
+
== Changelog ==
|
61 |
+
|
62 |
+
= 0.8 =
|
63 |
+
* Fixed an issue resulting in a black image, when image was cropped without moving the crop handles
|
64 |
+
|
65 |
+
= 0.7 =
|
66 |
+
* Fixed return types other than image id causing fatal error
|
67 |
+
|
68 |
+
= 0.6 =
|
69 |
+
* Fix for WP installs with non-standard folder structures
|
70 |
+
|
71 |
+
= 0.5 =
|
72 |
+
* Initial Release.
|
73 |
+
|