implemented cropping and selection of images
This commit is contained in:
parent
ee4591e60a
commit
51859ae136
|
|
@ -16,7 +16,6 @@ function gallery_app_init($hook) {
|
|||
|
||||
$gallery_app_dir = plugin_dir_url(__FILE__) . 'gallery';
|
||||
|
||||
|
||||
/*
|
||||
* Dependencies
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -6,14 +6,26 @@ function admin_gallery_html($args) {
|
|||
<div class="wrap">
|
||||
<h1>Gallery</h1>
|
||||
|
||||
<div id="notice-container"></div>
|
||||
|
||||
<div class="theatergf gallery_app">
|
||||
|
||||
<div class="theatergf gallery-container">
|
||||
<div class="gallery"></div>
|
||||
<div class="spinner-container">
|
||||
<span class="spinner"></span>
|
||||
</div>
|
||||
</div>
|
||||
<button id="theatergf-save-selected" class="button button-primary">Save Selected</button>
|
||||
|
||||
<div style="height: 2px; background-color: black; margin: 5px 0;"></div>
|
||||
|
||||
<div id="theatergf-editor" class="theatergf image-editor">
|
||||
<img class="editor-image">
|
||||
</div>
|
||||
<div class="editor-button-row">
|
||||
<button id="theatergf-select-image" class="button button-primary">Select image</button>
|
||||
<button id="theatergf-edit-save" class="button button-primary">Save</button
|
||||
<button id="theatergf-edit-save" class="button button-primary">Save</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,25 @@ function getRelativeClientRect(element) {
|
|||
);
|
||||
}
|
||||
|
||||
function createNotice(type, message) {
|
||||
const element = document.createElement('div')
|
||||
|
||||
element.className = `notice notice-${type} is-dismissible`;
|
||||
element.innerHTML = `<p>${message}</p>`;
|
||||
|
||||
document.querySelector('#notice-container').appendChild(element);
|
||||
|
||||
jQuery(document).trigger('wp-updates-notice-added');
|
||||
}
|
||||
|
||||
function createSuccessNotice(message) {
|
||||
return createNotice("success", message);
|
||||
}
|
||||
|
||||
function createErrorNotice(message) {
|
||||
return createNotice("error", message);
|
||||
}
|
||||
|
||||
class ResizableBox {
|
||||
constructor(parent, bounding, resolution, aspectRatio = null) {
|
||||
|
||||
|
|
@ -206,8 +225,8 @@ class ResizableBox {
|
|||
const rect = getRelativeClientRect(this.element);
|
||||
|
||||
return new DOMRect(
|
||||
Math.floor(rect.x * this.scale.x),
|
||||
Math.floor(rect.y * this.scale.y),
|
||||
Math.floor((rect.x - this.bounding.x) * this.scale.x),
|
||||
Math.floor((rect.y - this.bounding.y) * this.scale.y),
|
||||
Math.floor(rect.width * this.scale.x),
|
||||
Math.floor(rect.height * this.scale.y)
|
||||
);
|
||||
|
|
@ -316,9 +335,13 @@ class Editor {
|
|||
this.aspectRatio = aspectRatio;
|
||||
|
||||
this._imgElement = undefined;
|
||||
|
||||
this._img_id = null;
|
||||
}
|
||||
|
||||
loadImage(url) {
|
||||
loadImage(img_id, url) {
|
||||
this.img_id = img_id;
|
||||
|
||||
this._imgElement = this._editor.querySelector(".editor-image");
|
||||
this._imgElement.src = url;
|
||||
|
||||
|
|
@ -343,24 +366,268 @@ class Editor {
|
|||
|
||||
console.log(region)
|
||||
|
||||
fetch(wpAPISettings.root + 'theatergf/gallery/v1/crop/new', {
|
||||
fetch(wpAPISettings.root + 'theatergf/gallery/v1/images/new', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-WP-Nonce': wpAPISettings.nonce,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
img_id: 53,
|
||||
img_id: this.img_id,
|
||||
x: region.x,
|
||||
y: region.y,
|
||||
width: region.width,
|
||||
height: region.height
|
||||
})
|
||||
}).then((response) => response.json().then((json) => console.log(json))).catch((error) => console.log(error));
|
||||
}).then((response) => {
|
||||
|
||||
response.json().then((json) => {
|
||||
if (response.ok) {
|
||||
console.log("response:", json)
|
||||
|
||||
createSuccessNotice("Successfully created");
|
||||
} else {
|
||||
createErrorNotice(`Failed to create image: ${json?.error ?? "Unknown Error"}`);
|
||||
}
|
||||
}).catch((error) => {
|
||||
createErrorNotice(`Failed to parse response: ${error}`);
|
||||
})
|
||||
|
||||
}).catch((error) => {
|
||||
createErrorNotice(`Failed to connect to backend: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class GalleryItemElement extends HTMLElement {
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["src", "selected"];
|
||||
}
|
||||
|
||||
get imageId() { return this.getAttribute("image-id"); }
|
||||
set imageId(value) { this.setAttribute("image-id", value); }
|
||||
|
||||
get src() { return this.getAttribute("src"); }
|
||||
set src(value) { this.setAttribute("src", value); }
|
||||
|
||||
get selected() { return this.getAttribute("selected"); }
|
||||
set selected(value) { this.setAttribute("selected", value); }
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadow = this.attachShadow({ mode: "open" });
|
||||
|
||||
// Container
|
||||
this.container = document.createElement("div");
|
||||
this.container.classList.add("image-container");
|
||||
|
||||
this.numbering = document.createElement("div");
|
||||
this.numbering.classList.add("numbering");
|
||||
|
||||
// Spinner
|
||||
this.spinner = document.createElement("span");
|
||||
this.spinner.classList.add("spinner", "is-active");
|
||||
|
||||
// Image
|
||||
this.image = document.createElement("img");
|
||||
|
||||
this.image.addEventListener("load", () => {
|
||||
this.spinner.classList.remove("is-active");
|
||||
});
|
||||
|
||||
this.image.addEventListener("error", () => {
|
||||
this.spinner.classList.remove("is-active");
|
||||
});
|
||||
|
||||
this.container.appendChild(this.spinner);
|
||||
this.container.appendChild(this.numbering);
|
||||
this.container.appendChild(this.image);
|
||||
|
||||
// Styles
|
||||
const style = document.createElement("style");
|
||||
style.textContent = `
|
||||
.image-container {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
border: black solid 1px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.image-container.selected {
|
||||
border: blue solid 3px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.numbering {
|
||||
position: absolute;
|
||||
right: -3px;
|
||||
bottom: -3px;
|
||||
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
|
||||
text-align: center;
|
||||
line-height: 1.5em;
|
||||
|
||||
background-color: blue;
|
||||
color: white;
|
||||
|
||||
visibility: hidden;
|
||||
}
|
||||
.image-container.selected .numbering {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.spinner:not(.is-active) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
shadow.appendChild(style);
|
||||
shadow.appendChild(this.container);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.updateImage();
|
||||
this.updateSelected();
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue === newValue) return;
|
||||
|
||||
if (name === "src") {
|
||||
this.updateImage();
|
||||
}
|
||||
|
||||
if (name === "selected") {
|
||||
this.updateSelected();
|
||||
}
|
||||
}
|
||||
|
||||
updateImage() {
|
||||
const src = this.getAttribute("src");
|
||||
|
||||
if (!src) return;
|
||||
|
||||
this.image.src = src;
|
||||
this.spinner.classList.add("is-active");
|
||||
}
|
||||
|
||||
updateSelected() {
|
||||
if (this.hasAttribute("selected") && this.getAttribute("selected")) {
|
||||
this.container.classList.add("selected");
|
||||
this.numbering.innerHTML = this.getAttribute("selected");
|
||||
} else {
|
||||
this.container.classList.remove("selected");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
customElements.define("ttgf-gallery-item", GalleryItemElement)
|
||||
|
||||
/*function create_gallery_element(image_src) {
|
||||
const element = document.createElement("div");
|
||||
element.classList.add("image-container")
|
||||
|
||||
const spinner = document.createElement("span");
|
||||
spinner.classList.add("spinner", "is-active");
|
||||
element.appendChild(spinner);
|
||||
|
||||
const image_element = new Image();
|
||||
|
||||
image_element.addEventListener('load', (_) => {
|
||||
spinner.classList.remove("is-active")
|
||||
})
|
||||
image_element.addEventListener('error', (_) => {
|
||||
spinner.classList.remove("is-active")
|
||||
})
|
||||
|
||||
image_element.src = image_src
|
||||
element.appendChild(image_element)
|
||||
|
||||
return element;
|
||||
}*/
|
||||
|
||||
function create_gallery_element(id, image_src, selected) {
|
||||
const e = document.createElement("ttgf-gallery-item");
|
||||
e.imageId = id;
|
||||
e.src = image_src;
|
||||
e.selected = selected;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
async function load_gallery() {
|
||||
|
||||
const spinner = document.querySelector('.gallery-container .spinner');
|
||||
spinner.classList.add("is-active");
|
||||
|
||||
const gallery = document.querySelector('.gallery');
|
||||
|
||||
try {
|
||||
const response = await fetch(wpAPISettings.root + 'theatergf/gallery/v1/images/all', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'X-WP-Nonce': wpAPISettings.nonce
|
||||
},
|
||||
})
|
||||
|
||||
const json = await response.json()
|
||||
console.log(json);
|
||||
|
||||
if (!Array.isArray(json)) {
|
||||
throw TypeError(`Did not receive an array of posts as a result! Got ${typeof json}`)
|
||||
}
|
||||
|
||||
if (json.length == 0) {
|
||||
gallery.innerHTML = "<p>No images yet</p>";
|
||||
return;
|
||||
}
|
||||
|
||||
json.forEach((v) => {
|
||||
const item = create_gallery_element(v["ID"], v["thumbnail_src"], v["selected"])
|
||||
item.addEventListener("click", (e) => {
|
||||
selected_items = Array.from(gallery.querySelectorAll("ttgf-gallery-item")).filter((v) => v.selected > 0)
|
||||
if (e.target.selected) {
|
||||
|
||||
selected_items.filter((v) => v.selected > e.target.selected).forEach((v) => v.selected = (Number(v.selected)-1).toString())
|
||||
|
||||
e.target.selected = ""
|
||||
} else {
|
||||
selected_items.forEach((v) => v.selected = (Number(v.selected)+1).toString());
|
||||
e.target.selected = "1"
|
||||
}
|
||||
})
|
||||
gallery.appendChild(item)
|
||||
})
|
||||
|
||||
|
||||
} catch (e) {
|
||||
createErrorNotice(`Failed to load available images: ${e}`)
|
||||
|
||||
gallery.innerHTML = "<p>Error loading images</p>";
|
||||
} finally {
|
||||
spinner.classList.remove("is-active");
|
||||
}
|
||||
}
|
||||
|
||||
jQuery(document).ready( ($) => {
|
||||
let wp_file_selector_frame = null;
|
||||
|
|
@ -388,7 +655,7 @@ jQuery(document).ready( ($) => {
|
|||
|
||||
console.log(file)
|
||||
|
||||
editor.loadImage(file.url);
|
||||
editor.loadImage(file.id, file.url);
|
||||
});
|
||||
|
||||
wp_file_selector_frame.open();
|
||||
|
|
@ -398,5 +665,48 @@ jQuery(document).ready( ($) => {
|
|||
event.preventDefault();
|
||||
|
||||
editor.save();
|
||||
|
||||
load_gallery();
|
||||
})
|
||||
|
||||
$("#theatergf-save-selected").on('click', (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
console.log("click");
|
||||
|
||||
const gallery = document.querySelector('.gallery');
|
||||
|
||||
const items = gallery.querySelectorAll("ttgf-gallery-item");
|
||||
const payload = Array.from(items, (v) => ({ ID: v.imageId, selected: v.selected }))
|
||||
|
||||
fetch(wpAPISettings.root + 'theatergf/gallery/v1/images/selected/set', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-WP-Nonce': wpAPISettings.nonce,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
imgs: payload
|
||||
})
|
||||
}).then((response) => {
|
||||
|
||||
response.json().then((json) => {
|
||||
if (response.ok) {
|
||||
console.log("response:", json)
|
||||
|
||||
createSuccessNotice("Saved.");
|
||||
} else {
|
||||
createErrorNotice(`Failed to save selected image: ${json?.code ?? "Unknown Error"}`);
|
||||
}
|
||||
}).catch((error) => {
|
||||
createErrorNotice(`Failed to parse response: ${error}`);
|
||||
})
|
||||
|
||||
}).catch((error) => {
|
||||
createErrorNotice(`Failed to connect to backend: ${error}`);
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
load_gallery();
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,90 @@
|
|||
|
||||
#theatergf-editor-status {
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.theatergf {
|
||||
|
||||
.gallery-container {
|
||||
width: 75%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
|
||||
.gallery {
|
||||
border: black 1px solid;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-content: top;
|
||||
justify-content: left;
|
||||
flex-wrap: wrap;
|
||||
gap: 5px;
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
|
||||
p {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
|
||||
position: relative;
|
||||
|
||||
border: black solid 1px;
|
||||
|
||||
&.selected {
|
||||
border: blue solid 3px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.numbering {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
|
||||
background-color: blue;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
.spinner:not(.is-active) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.spinner-container {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.spinner {
|
||||
display: block;
|
||||
float: none;
|
||||
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.image-editor {
|
||||
aspect-ratio: 2 / 1;
|
||||
width: 75%;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,35 @@ require_once __DIR__ . '/endpoints/crop.php';
|
|||
add_action( 'rest_api_init', function () {
|
||||
$namespace = 'theatergf/gallery/v1';
|
||||
|
||||
$crop_controller = new Rest\CROP_Endpoints($namespace, 'crop');
|
||||
$crop_controller = new Rest\CROP_Endpoints($namespace, 'images');
|
||||
$crop_controller->register_routes();
|
||||
});
|
||||
|
||||
add_action( 'delete_attachment', function ( $post_id ) {
|
||||
$selected = get_post_meta($post_id, '_ttgf_gallery_selected', true);
|
||||
|
||||
error_log("deleting: " . $post_id . ", selected: " . $selected);
|
||||
|
||||
if ( (! $selected) || empty($selected) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$posts = get_posts(array(
|
||||
'numberposts' => -1,
|
||||
'post_type' => "attachment",
|
||||
'meta_key' => "_ttgf_gallery_selected",
|
||||
'meta_value' => (int)$selected,
|
||||
'meta_type' => 'NUMERIC',
|
||||
'meta_compare' => '>'
|
||||
));
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$s = get_post_meta($post->ID, '_ttgf_gallery_selected', true);
|
||||
|
||||
if ( (! $selected) || empty($selected) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
update_post_meta($post->ID, '_ttgf_gallery_selected', ((int)$s - 1));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,15 @@
|
|||
|
||||
namespace TheaterGF\Gallery\Backend\Rest;
|
||||
|
||||
class CROP_Endpoints extends \WP_REST_Controller {
|
||||
require_once ABSPATH . "wp-content/plugins/theatergf-core/src/media.php";
|
||||
|
||||
use \WP_Error;
|
||||
use \WP_REST_Controller;
|
||||
use \WP_REST_Server;
|
||||
|
||||
use function \TheaterGF\Core\get_media_manager;
|
||||
|
||||
class CROP_Endpoints extends WP_REST_Controller {
|
||||
|
||||
public function __construct( $namespace, $base_path ) {
|
||||
$this->namespace = $namespace;
|
||||
|
|
@ -11,53 +19,183 @@ class CROP_Endpoints extends \WP_REST_Controller {
|
|||
|
||||
public function register_routes() {
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->rest_base . '/all', [
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => [ $this, 'get_items' ],
|
||||
'permission_callback' => [ $this, 'get_items_permissions_check'],
|
||||
'args' => []
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->rest_base . '/selected/set', [
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => [ $this, 'set_selected' ],
|
||||
'permission_callback' => [ $this, 'create_item_permissions_check' ],
|
||||
'args' => [
|
||||
'imgs' => [
|
||||
'required' => true,
|
||||
'validate_callback' => function ( $param, $request, $key) {
|
||||
if ( ! is_array($param) ) {
|
||||
return false;
|
||||
}
|
||||
foreach ( $param as $img ) {
|
||||
if ( ! (wp_attachment_is_image($img['ID']) && (is_numeric($img['selected']) || empty($img['selected']))) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
register_rest_route($this->namespace, '/' . $this->rest_base . '/new', [
|
||||
'methods' => \WP_REST_Server::CREATABLE,
|
||||
'callback' => [ $this, 'create_item' ],
|
||||
'permission_callback' => [ $this, 'create_item_permissions_check' ],
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => [ $this, 'create_item' ],
|
||||
'permission_callback' => [ $this, 'create_item_permissions_check' ],
|
||||
'args' => [
|
||||
'img_id' => [
|
||||
'required' => true,
|
||||
'required' => true,
|
||||
'validate_callback' => function ( $param, $request, $key) { return wp_attachment_is_image($param); }
|
||||
],
|
||||
'x' => [
|
||||
'required' => true,
|
||||
'required' => true,
|
||||
'validate_callback' => function ( $param, $request, $key) { return is_numeric($param) && $param >= 0; }
|
||||
],
|
||||
'y' => [
|
||||
'required' => true,
|
||||
'required' => true,
|
||||
'validate_callback' => function ( $param, $request, $key) { return is_numeric($param) && $param >= 0; }
|
||||
],
|
||||
'width' => [
|
||||
'required' => true,
|
||||
'required' => true,
|
||||
'validate_callback' => function ( $param, $request, $key) { return is_numeric($param) && $param > 0; }
|
||||
],
|
||||
'height' => [
|
||||
'required' => true,
|
||||
'required' => true,
|
||||
'validate_callback' => function ( $param, $request, $key) { return is_numeric($param) && $param > 0; }
|
||||
]
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_items_permissions_check( $request ) {
|
||||
return $this->editable_permission_check($request);
|
||||
}
|
||||
|
||||
public function create_item_permissions_check( $request ) {
|
||||
return $this->editable_permission_check($request);
|
||||
}
|
||||
|
||||
if ( ! is_user_logged_in()) {
|
||||
return new \WP_Error( 'unauthenticated', 'Log in to interact with this endpoint.', array( 'status' => 401 ));
|
||||
|
||||
public function get_items( $request ) {
|
||||
|
||||
$posts = get_posts(array(
|
||||
'numberposts' => -1,
|
||||
'post_type' => "attachment",
|
||||
'meta_key' => "_ttgf_is_gallery_crop",
|
||||
'meta_value' => true
|
||||
));
|
||||
|
||||
$return_data = [];
|
||||
|
||||
foreach ($posts as $post) {
|
||||
$thumbnail_src = wp_get_attachment_image_src($post->ID, "thumbnail");
|
||||
if ( is_wp_error($thumbnail_src) ) {
|
||||
error_log($thumbnail_src->get_error_message());
|
||||
continue;
|
||||
}
|
||||
$image_src = wp_get_attachment_image_src($post->ID, "full");
|
||||
if ( is_wp_error($image_src) ) {
|
||||
error_log($image_src->get_error_message());
|
||||
continue;
|
||||
}
|
||||
|
||||
$selected = get_post_meta($post->ID, '_ttgf_gallery_selected', true);
|
||||
|
||||
$return_data[] = [
|
||||
"post" => $post,
|
||||
"ID" => $post->ID,
|
||||
"thumbnail_src" => $thumbnail_src[0],
|
||||
"image_src" => $image_src[0],
|
||||
"selected" => $selected
|
||||
];
|
||||
}
|
||||
|
||||
if ( ! (is_user_logged_in() && current_user_can( 'edit_pages' )) ) {
|
||||
return new \WP_Error( 'forbidden', 'No Permission for this endpoint.', array( 'status' => 403 ));
|
||||
return $return_data;
|
||||
}
|
||||
|
||||
public function set_selected( $request ) {
|
||||
$params = $request->get_json_params();
|
||||
|
||||
foreach ( $params["imgs"] as $img ) {
|
||||
update_post_meta($img["ID"], '_ttgf_gallery_selected', $img["selected"]);
|
||||
}
|
||||
|
||||
return true;
|
||||
return $params;
|
||||
}
|
||||
|
||||
public function create_item( $request ) {
|
||||
|
||||
//$image = get_attached_file()
|
||||
$params = $request->get_json_params();
|
||||
|
||||
$image_name = basename(wp_get_original_image_path($params['img_id']));
|
||||
|
||||
// load wp_crop_image
|
||||
require_once ABSPATH . 'wp-admin/includes/image.php';
|
||||
|
||||
$cropped = wp_crop_image(
|
||||
$params["img_id"], // id of base image
|
||||
$params["x"], // coordinates
|
||||
$params["y"],
|
||||
$params["width"], // size of rectangle in source image
|
||||
$params["height"],
|
||||
$params["width"], // size of destination image (resized)
|
||||
$params["height"],
|
||||
false, // coordinates are relative to image
|
||||
\TheaterGF\Gallery\get_uploads_dir() . "/cropped-" . time() . "-" . $image_name
|
||||
);
|
||||
|
||||
if ( is_wp_error($cropped) ) {
|
||||
return $cropped;
|
||||
}
|
||||
|
||||
$attachment_data = [
|
||||
'guid' => \TheaterGF\Gallery\generate_guid($cropped),
|
||||
'post_mime_type' => wp_get_image_mime($cropped),
|
||||
'post_title' => basename($cropped),
|
||||
/*// optional
|
||||
'post_excerpt' => $caption,
|
||||
'post_content' => $description*/
|
||||
];
|
||||
$new_attachment_id = wp_insert_attachment($attachment_data, $cropped, 0, true);
|
||||
|
||||
if ( is_wp_error($new_attachment_id) ) {
|
||||
return $new_attachment_id;
|
||||
}
|
||||
|
||||
$metadata = wp_generate_attachment_metadata($new_attachment_id, $cropped);
|
||||
wp_update_attachment_metadata($new_attachment_id, $metadata);
|
||||
|
||||
update_post_meta($new_attachment_id, '_ttgf_is_gallery_crop', true);
|
||||
update_post_meta($new_attachment_id, '_ttgf_original_img_id', $params["img_id"]);
|
||||
|
||||
$tags = get_media_manager()->tags->get_from_post($params["img_id"]);
|
||||
|
||||
get_media_manager()->post_add_tags($new_attachment_id, $tags);
|
||||
get_media_manager()->post_mark_generated($new_attachment_id);
|
||||
|
||||
return [ "params" => $params, "image" => get_post_meta($new_attachment_id) ];
|
||||
}
|
||||
|
||||
|
||||
protected function editable_permission_check( $request ) {
|
||||
|
||||
if ( ! is_user_logged_in()) {
|
||||
return new WP_Error( 'unauthenticated', 'Log in to interact with this endpoint.', array( 'status' => 401 ));
|
||||
}
|
||||
|
||||
if ( ! (is_user_logged_in() && current_user_can( 'edit_pages' )) ) {
|
||||
return new WP_Error( 'forbidden', 'No Permission for this endpoint.', array( 'status' => 403 ));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace TheaterGF\Gallery\Backend\Rest;
|
||||
|
||||
use \WP_Error;
|
||||
use \WP_REST_Controller;
|
||||
use \WP_REST_Server;
|
||||
|
||||
class GALLERY_Endpoints extends WP_REST_Controller {
|
||||
|
||||
public function __construct( $namespace, $base_path ) {
|
||||
$this->namespace = $namespace;
|
||||
$this->rest_base = $base_path;
|
||||
}
|
||||
|
||||
|
||||
public function register_routes() {
|
||||
register_rest_route($this->namespace, '/' . $this->rest_base, [
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => [ $this, 'get_items' ],
|
||||
'permission_callback' => [ $this, 'get_items_permissions_check'],
|
||||
'args' => []
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_items_permissions_check( $request ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_items( $request ) {
|
||||
$posts = get_posts(array(
|
||||
'numberposts' => -1,
|
||||
'post_type' => "attachment",
|
||||
'meta_key' => "_ttgf_gallery_selected",
|
||||
));
|
||||
|
||||
$data = []
|
||||
|
||||
foreach ( $posts as $post ) {
|
||||
$data[] = wp_get_attachment_image_src($post->ID, "full");
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace TheaterGF\Gallery\Backend;
|
||||
|
||||
/**
|
||||
* Checks whether all required fields are present. Does not support duplicate keys.
|
||||
*
|
||||
* @return if a field is missing, its key, otherwise null
|
||||
*/
|
||||
function check_required_fields(WP_REST_Request $request, iterable $fields): string|null {
|
||||
|
||||
foreach ($fields as $key) {
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -18,6 +18,16 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
function get_uploads_dir() {
|
||||
return wp_upload_dir()["basedir"] . "/theatergf/gallery";
|
||||
}
|
||||
|
||||
function generate_guid( $filename ) {
|
||||
$upload_dirs = wp_upload_dir();
|
||||
|
||||
return $upload_dirs["baseurl"] . '/' . str_replace($upload_dirs["basedir"] . '/', "", $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the block(s) metadata from the `blocks-manifest.php` and registers the block type(s)
|
||||
* based on the registered block metadata. Behind the scenes, it registers also all assets so they can be enqueued
|
||||
|
|
|
|||
Loading…
Reference in New Issue