Wordpress: Pass Image Data to Another Page - javascript

i'm a newbie. first sorry for my English. I'm here trying to make a website with wordpress and have some difficult time when i trying to modify a plugin function because i have no basic skill on programming, even a pro need time to edit another developer code.
But i'm here to learn, i have stuck on this function for like 1 month with out any progress and no results.
So, i have two plugin, one name "fancy product designer" is a Woocommerce Product editor where customer can create their own customized product on your site, and second one is "Dokan" is a multi marketplace, where a customer can act like a seller, build their own product, their price, named the product and etc.
Now, i want to integrate both plugin, where customer who want to sell in my site, they need to create their product via "Fancy Product Designer", and then Fill the information of that product (name, price, desc) on Dokan Add Product Pages. In the simple way, i want the image generated by "fancy product designer" is used as Product Featured Image on "Dokan" add product pages, where both of them is on different pages.
Because i was a newbie and no basic skill of coding, i don't know how to implement a code, what code use for, what result the code make, etc. But Here is some code needed to implement the function.
Here's some code of "Fancy Product Designer"
/**
* Creates an image of the current showing product.
*
* #method createImage
* #param {boolean} [openInBlankPage= true] Opens the image in a Pop-up window.
* #param {boolean} [forceDownload=false] Downloads the image to the user's computer.
* #param {string} [backgroundColor=transparent] The background color as hexadecimal value. For 'png' you can also use 'transparent'.
* #param {string} [options] See fabricjs documentation http://fabricjs.com/docs/fabric.Canvas.html#toDataURL.
*/
this.createImage = function(openInBlankPage, forceDownload, backgroundColor, options) {
if(typeof(openInBlankPage)==='undefined') openInBlankPage = true;
if(typeof(forceDownload)==='undefined') forceDownload = false;
backgroundColor = typeof backgroundColor !== 'undefined' ? backgroundColor : 'transparent';
options = typeof options !== 'undefined' ? options : {};
format = options.format === undefined ? 'png' : options.format;
instance.getProductDataURL(function(dataURL) {
var image = new Image();
image.src = dataURL;
image.onload = function() {
if(openInBlankPage) {
var popup = window.open('','_blank');
FPDUtil.popupBlockerAlert(popup, instance);
popup.document.title = "Product Image";
$(popup.document.body).append('<img src="'+this.src+'" download="product.'+format+'" />');
if(forceDownload) {
window.location.href = popup.document.getElementsByTagName('img')[0].src.replace('image/'+format+'', 'image/octet-stream');
}
}
}
}, backgroundColor, options);
/**
I don't know if it used, but its a code to generated the views (Product Canvas/ A layer of image that later joined and become Product Image) to dataURL
/**
* Gets the views as data URL.
*
* #method getViewsDataURL
* #param {Function} callback A function that will be called when the data URL is created. The function receives the data URL.
* #param {string} [backgroundColor=transparent] The background color as hexadecimal value. For 'png' you can also use 'transparent'.
* #param {string} [options] See fabricjs documentation http://fabricjs.com/docs/fabric.Canvas.html#toDataURL.
* #return {array} An array with all views as data URLs.
*/
this.getViewsDataURL = function(callback, backgroundColor, options) {
callback = typeof callback !== 'undefined' ? callback : function() {};
backgroundColor = typeof backgroundColor !== 'undefined' ? backgroundColor : 'transparent';
options = typeof options !== 'undefined' ? options : {};
var dataURLs = [];
for(var i=0; i < instance.viewInstances.length; ++i) {
instance.viewInstances[i].toDataURL(function(dataURL) {
dataURLs.push(dataURL);
if(dataURLs.length === instance.viewInstances.length) {
callback(dataURLs);
}
}, backgroundColor, options, instance.watermarkImg);
}
};
};
/**
* Creates all views in one data URL. The different views will be positioned below each other.
*
* #method getProductDataURL
* #param {Function} callback A function that will be called when the data URL is created. The function receives the data URL.
* #param {String} [backgroundColor=transparent] The background color as hexadecimal value. For 'png' you can also use 'transparent'.
* #param {Object} [options] See fabricjs documentation http://fabricjs.com/docs/fabric.Canvas.html#toDataURL.
* #example fpd.getProductDataURL( function(dataURL){} );
*/
this.getProductDataURL = function(callback, backgroundColor, options) {
callback = typeof callback !== 'undefined' ? callback : function() {};
backgroundColor = typeof backgroundColor !== 'undefined' ? backgroundColor : 'transparent';
options = typeof options !== 'undefined' ? options : {};
//check
if(instance.viewInstances.length === 0) { callback('') }
$body.append('<canvas id="fpd-hidden-canvas"></canvas>');
var printCanvas = new fabric.Canvas('fpd-hidden-canvas', {
containerClass: 'fpd-hidden fpd-hidden-canvas',
enableRetinaScaling: true
}),
viewCount = 0;
function _addCanvasImage(viewInstance) {
if(viewInstance.options.stageWidth > printCanvas.getWidth()) {
printCanvas.setDimensions({width: viewInstance.options.stageWidth});
}
viewInstance.toDataURL(function(dataURL) {
fabric.Image.fromURL(dataURL, function(img) {
printCanvas.add(img);
if(viewCount > 0) {
img.setTop(printCanvas.getHeight());
printCanvas.setDimensions({height: (printCanvas.getHeight() + viewInstance.options.stageHeight)});
}
viewCount++;
if(viewCount < instance.viewInstances.length) {
_addCanvasImage(instance.viewInstances[viewCount]);
}
else {
callback(printCanvas.toDataURL(options));
printCanvas.dispose();
$body.children('.fpd-hidden-canvas, #fpd-hidden-canvas').remove();
if(instance.currentViewInstance) {
instance.currentViewInstance.resetCanvasSize();
}
}
});
And here was the "Dokan" Plugin code to add featured image (note: I dont know if it could be a problem, but dokan can only upload the featured image from wordpress media, even there's an Upload options too but the file uploaded need to be on my computer.)
featuredImage: {
addImage: function(e) {
e.preventDefault();
var self = $(this);
if ( product_featured_frame ) {
product_featured_frame.open();
return;
}
product_featured_frame = wp.media({
// Set the title of the modal.
title: 'Upload featured image',
button: {
text: 'Set featured image',
}
});
product_featured_frame.on('select', function() {
var selection = product_featured_frame.state().get('selection');
selection.map( function( attachment ) {
attachment = attachment.toJSON();
// set the image hidden id
self.siblings('input.dokan-feat-image-id').val(attachment.id);
// set the image
var instruction = self.closest('.instruction-inside');
var wrap = instruction.siblings('.image-wrap');
// wrap.find('img').attr('src', attachment.sizes.thumbnail.url);
wrap.find('img').attr('src', attachment.url);
instruction.addClass('dokan-hide');
wrap.removeClass('dokan-hide');
});
});
product_featured_frame.open();
},
removeImage: function(e) {
e.preventDefault();
var self = $(this);
var wrap = self.closest('.image-wrap');
var instruction = wrap.siblings('.instruction-inside');
instruction.find('input.dokan-feat-image-id').val('0');
wrap.addClass('dokan-hide');
instruction.removeClass('dokan-hide');
}
}
If the code i give is doesn't help you, please ask me to another function and i will look for it.
Please help me to implement the code on html or php or both too so it will redirect from one to another. I have read How to pass extra variables in URL with Wordpress before and i think it could help, so i decided to trying use a param to define a featured image is from other site, but when i trying to use it on "Dokan" add product pages with ?feat_image_id=https://imageurl.com or ?dokan-featured-image=https://imageurl.com and some param that possible (i forget what is it) but nothing happens on that page.
Thank you very much for your attentions, and for everyone who want to help me

Related

JSDoc function returning a parameter of itself

I need to document a function returning conditionally one of its parameters. But JSDoc seems not to accept variables as a return value.
I tried to do something like this following the return type {1 | 0} logic
/**
* Finds the page with given index and returns
* - index if it does not exist
* - user if user doesn't have permissions to read
* - else the page itself
*
* #param {number} index
* #param {string} user
* #returns {index|user|Page}
*/
function getRead(index, user) {
let page = pages.find(page => page.details.index == index);
if (page && page.canRead(user)) {
return page;
} else if (!page) return index;
else return user;
}
But it is not recognized and the return values is just any, if i use {string|number|Page} as type, afterwards in my code I do something like this
if(page == index) return res.send(`Page ${index} does not exist`);
if(page == user) return res.send(`No permissions to view page ${index}`);
//page still recognized as number | string | Page
//no code completion or property suggestions on page
I also tried to add type checks to get there but i don't want to believe that like such a lazy the solution is the only one, there must be a better way to handle this
if(typeof page == "number" || page == index) return res.send(`Page ${index} does not exist`);
if(typeof page == "string" || page == user) return res.send(`No permissions to view page ${index}`);
//page recognized as Page
There are several solutions:
Use generic types for parameters
/**
* Finds the page with given index and returns
* - index if it does not exist
* - user if user doesn't have permissions to read
* - else the page itself
*
* #template {number} IndexType
* #template {string} UserType
* #param {IndexType} index
* #param {UserType} user
* #returns {IndexType|UserType|Page}
*/
function getRead(index, user) {
...
}
Remove JSDoc for the function at all and rely on TypeScript's type inference
function getRead(/**#type {number}*/index, /**#type {string}*/user) {
...
}

Restrict Routes in Javascript based on firebase authentication

I am building a javascript Application. This application is using a plugin called jq-router. When I do something like the following, the address bar changes but the view fails to change.
$.router.onRouteBeforeChange(function(e, route, params){
firebase.auth().onAuthStateChanged(function(user){
if(!user && route.protected) {
$.router.go('landing', {}); <!-- This line calls the plugin.
}
});
});
The function in the plugin that is called above looks like the following.
/**
* Navigates to given route name & params
* #params {string} routeName
* #params {object} params
* #return {object} this
*/
s.go = function(routeName, params) {
var s = this;
paramSrv.setParams(params);
window.location = s.href(routeName, params);
return s;
};
You can access the entire plugin here: https://github.com/muzammilkm/jq-router
Again, expected result is that the view and the address bar update. Currently the only thing updating is the address bar, the view still renders.
You should be using onViewChange/onRouteChanged events & also exclude the landing route avoid circular loop. onRouteBeforeChange event is intended to notify the route is about to change, so that if any clean up operation can be done.
$.router.onViewChange(function(e, viewRoute, route, params){
firebase.auth().onAuthStateChanged(function(user){
if(!user && route.name !== "landing" && route.protected) {
$.router.go('landing', {}); <!-- This line calls the plugin.
}
});
});

Textbox for Logmessages HTML/JS

Before creating an own solution I tried finding something which already suits my needs. I have got a node.js server where multiple clients / applications connect to. These clients will send log messages to the server which I would like to display in a panel.
Now there are some feature I that I need for a typical multiline textbox for logmessages:
I need to be able to append log messages as they will be send regularly via websockets
It should autoscrolldown unless the user is selecting text or scrolling up
It should be able to use colors and bold/regular
My question:
Is there already a solution for the above use case?
Can I give you my example? It used to be a textarea but I've refactored it to a div with little code changes.
Some highlights of the code, available on github
A custom function to send log messages:
/**
* Add a message to the gamelog
* #param {Object} options : allows custom output
* #param {String} options.message : the message to display
* #param {Boolean} options.isTimed : does the message has a timestamp in front of it?
* #param {Boolean} options.isError : is the message an error?
* #param {Boolean} options.isNewline : start the message on a new line
*/
addMessage: function (options) {
var instance = ns.instance,
audio = instance.audio,
audiofx = audio.settings.fx,
history = this.areaMessage.html();
// isTimed?
options.message = options.isTimed
? history + this.fieldClock.val() + ': ' + options.message
: history + options.message;
// isNewline?
if (options.isNewline) {
options.message = options.message + '<br />';
}
// message
this.areaMessage.html(options.message);
this.scrollTop(this.areaMessage);
// isError?
if (options.isError) {
audio.play(audiofx.error);
}
},
A scroll to top function:
/**
* Automatically scroll down (from the top)
* #param {Object} target : jQuery object
*/
scrollTop: function (target) {
target.scrollTop(99999);
target.scrollTop(target.scrollTop() * 12);
}
To use colored messages you should be able to use an HTML string:
log.addMessage({
message: '<span style="color: red;">[ERROR]</span> ',
isNewLine: false
});
log.addMessage({
message: 'the rest of the error message',
isNewLine: true
});
Feel free to use this idea to enroll your own custom message box.

Explain where "this" points to

I'm working through the Chrome extension tutorial (full code below). There is one thing I don't understand about this, which is related to line 3 of the requestKittens method
req.onload = this.showPhotos_.bind(this);
and line 1 of the showPhotos method:
var kittens = e.target.responseXML.querySelectorAll('photo');
I'm trying to understand how e.target.responseXML points to the response XML of the request. Here's what I think so far: In the line that calls this function (3rd line of requestKittens()), this points to the kittenGenerator object, meaning that kittenGenerator is bound as the first argument for showPhotos(). So the argument e in showPhotos() should be kittenGenerator, right?
If that's true, then the first line of showPhotos()...
var kittens = e.target.responseXML.querySelectorAll('photo');
...is saying that kittenGenerator has a property target. However I checked this in the Chrome console and it doesn't - so there's a mistake in my logic. Anyone able to help?
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Global variable containing the query we'd like to pass to Flickr. In this
* case, kittens!
*
* #type {string}
*/
var QUERY = 'kittens';
var kittenGenerator = {
/**
* Flickr URL that will give us lots and lots of whatever we're looking for.
*
* See http://www.flickr.com/services/api/flickr.photos.search.html for
* details about the construction of this URL.
*
* #type {string}
* #private
*/
searchOnFlickr_: 'https://secure.flickr.com/services/rest/?' +
'method=flickr.photos.search&' +
'api_key=90485e931f687a9b9c2a66bf58a3861a&' +
'text=' + encodeURIComponent(QUERY) + '&' +
'safe_search=1&' +
'content_type=1&' +
'sort=interestingness-desc&' +
'per_page=20',
/**
* Sends an XHR GET request to grab photos of lots and lots of kittens. The
* XHR's 'onload' event is hooks up to the 'showPhotos_' method.
*
* #public
*/
requestKittens: function() {
var req = new XMLHttpRequest();
req.open("GET", this.searchOnFlickr_, true);
req.onload = this.showPhotos_.bind(this);
req.send(null);
},
/**
* Handle the 'onload' event of our kitten XHR request, generated in
* 'requestKittens', by generating 'img' elements, and stuffing them into
* the document for display.
*
* #param {ProgressEvent} e The XHR ProgressEvent.
* #private
*/
showPhotos_: function (e) {
var kittens = e.target.responseXML.querySelectorAll('photo');
for (var i = 0; i < kittens.length; i++) {
var img = document.createElement('img');
img.src = this.constructKittenURL_(kittens[i]);
img.setAttribute('alt', kittens[i].getAttribute('title'));
document.body.appendChild(img);
}
},
/**
* Given a photo, construct a URL using the method outlined at
* http://www.flickr.com/services/api/misc.urlKittenl
*
* #param {DOMElement} A kitten.
* #return {string} The kitten's URL.
* #private
*/
constructKittenURL_: function (photo) {
return "http://farm" + photo.getAttribute("farm") +
".static.flickr.com/" + photo.getAttribute("server") +
"/" + photo.getAttribute("id") +
"_" + photo.getAttribute("secret") +
"_s.jpg";
}
};
// Run our kitten generation script as soon as the document's DOM is ready.
document.addEventListener('DOMContentLoaded', function () {
kittenGenerator.requestKittens();
});
The first parameter of bind defines the context of partial application.
req.onload = this.showPhotos_.bind(this);
works because XMLHttpRequest uses event as its first parameter on it's onload handler. That's where e.target comes from.
To give you a simple example of bind, consider the following:
function add(a, b) {
return a + b;
}
var addTwo = add.bind(null, 2);
addTwo(10); // yields 12
If you define a context for bind (ie. something else than null), then you can access that context using this within the function.

Ember-Data: Restful Put

I am am trying to do a simple restful put command. My problem is that I need to do a put command into a different end point to my store.
I have my rest adapter
DS.RESTAdapter.reopen({
namespace: 'datastore'
});
I need to be able to call an end point, but not sure how to do it;
Something like,
store('foundItems', JSON)
Where foundItems is the end point.
you'll want to create a custom RESTAdapter and override buildURL, this should help you start
App.PeopleAdapter = DS.RESTAdapter.extend({
host: 'http://www.google.com',
namespace: 'api/v1',
/**
Builds a URL for a given type and optional ID.
By default, it pluralizes the type's name (for example,
'post' becomes 'posts' and 'person' becomes 'people').
If an ID is specified, it adds the ID to the path generated
for the type, separated by a `/`.
#method buildURL
#param {String} type
#param {String} id
#returns String
*/
buildURL: function(type, id) {
var url = [],
host = get(this, 'host'),
prefix = this.urlPrefix();
if (type) { url.push(this.pathForType(type)); }
if (id) { url.push(id); }
if (prefix) { url.unshift(prefix); }
url = url.join('/');
if (!host && url) { url = '/' + url; }
return url;
},
});

Categories