I'm trying to let user edit files they uploaded before.
I created a script, that returns the same HTML as is generated when I upload file.
function add_fineuploader_images () {
$post_id = $_POST['post_id'];
$media = get_attached_media( 'image', $post_id);
if ($media) {
foreach ($media as $image) {
?>
<li class="qq-file-id-0 qq-upload-success" qq-file-id="0" data-id="<?php echo $image->ID; ?>">
<span class="qq-upload-spinner-selector qq-upload-spinner qq-hide"></span>
<img class="qq-thumbnail-selector" qq-max-size="100" qq-server-scale="" src="<?php echo wp_get_attachment_image( $image->ID, 'thumbnail' );?>">
<span class="qq-edit-filename-icon-selector qq-edit-filename-icon"></span>
<span class="qq-upload-file-selector qq-upload-file"><?php echo $image->post_title; ?></span>
<input class="qq-edit-filename-selector qq-edit-filename" tabindex="0" type="text">
<a class="qq-upload-cancel-selector qq-upload-cancel qq-hide" href="#">Cancel</a>
<a class="qq-upload-retry-selector qq-upload-retry qq-hide" href="#">Retry</a>
<a class="qq-upload-delete-selector qq-upload-delete" href="#">Delete</a>
<a class="qq-upload-featured-selector qq-upload-set-featured" href="#">Set as featured</a>
<span class="qq-upload-status-text-selector qq-upload-status-text"></span>
</li>
<?php
}
}
exit();
}
And on page load I'm calling AJAX Post to load the images into page:
var post_id = $('#post_id').val();
$.post(Ajax.ajaxurl, { action: 'add_fineuploader_images', post_id: post_id }, function(data) {
console.log(data);
$('.qq-upload-list').html(data);
});
This created the same preview, as when the files are uploaded via FineUploader.
Now, I would need to let FineUploader know about these, so DELETE and other methods work.
I initialize FineUploader like this:
$("#fine-uploader").fineUploader({
request: {
endpoint: Ajax.ajaxurl,
params: {
action: 'attach_files',
post_id: $('#post_id').val()
}
},
deleteFile: {
enabled: true,
endpoint: Ajax.ajaxurl,
method: 'POST'
}
});
How should I reinitialize FineUploader? Or, is there a better way to do this?
If you want to display files in the upload list that have been uploaded in a previous session, just use the Initial File List feature. No need to reinvent the wheel here. If you want to reset Fine Uploader, use the reset API method.
I've noticed that you are asking a lot of questions that are covered in the documentation. I encourage you to take a close look at the existing documentation and demos, which, we hope, are fairly comprehensive.
Related
This is kind of a difficult question to pose as I don't have a lot of backend knowledge so forgive me if my jargon is not up to par.
Basically, I have a gallery of images and I need users to be able to "like" an image and have that increment a counter which then is stored to the server. So, if say 50 users liked a particular image, it would show "50" on that image to all users.
I'm assuming php and ajax are the best bet here.
Any help would be greatly appreciated.
Okay, here an example for a very simple like mechanism.
NOTE:
This example use jQuery.
For simplicity there is no Database, as db it use a simple json store.
There is no "unlike" function, it always increase the likes...
First we need our Gallery Markup:
<ul>
<li><a class="likeLink" data-imageid="1"><img src="https://dummyimage.com/100x100/000/fff" /><span class="likes">0</span></a></li>
<li><a class="likeLink" data-imageid="2"><img src="https://dummyimage.com/100x100/000/fff" /><span class="likes">0</span></a></li>
<li><a class="likeLink" data-imageid="3"><img src="https://dummyimage.com/100x100/000/fff" /><span class="likes">0</span></a></li>
<li><a class="likeLink" data-imageid="4"><img src="https://dummyimage.com/100x100/000/fff" /><span class="likes">0</span></a></li>
</ul>
data-imageid: This is our reference for the likes set on an image
< span class="likes" >: just a litte container that show likes for an image
Now we need a "store", in this example case a simple json object:
{
"images":[
{"imageId":1,"likes":0},
{"imageId":2,"likes":0},
{"imageId":3,"likes":0},
{"imageId":4,"likes":0}
]
}
Next we need is a bit JavaScript:
$(document).ready(function(){
// Initial loading likes for images
$.ajax({
type: 'GET',
url: 'setlike.php?getAllLikes',
success: function (data) {
$.each(data.images, function(index, value){
$('.likeLink[data-imageid="'+ value.imageId +'"]').find('.likes').html(value.likes);
});
}
});
// Set a like for an image
$('.likeLink').on('click', function(){
var imageId = $(this).attr('data-imageid');
$.ajax({
type: 'POST',
url: 'setlike.php',
data: { imageId: imageId },
success: function (data) {
$('.likeLink[data-imageid="'+ data.imageId +'"]').find('.likes').html(data.likes);
}
});
})
})
Last but not least, we need a php script that handle our ajax requests:
header('Content-Type: application/json');
$data = file_get_contents('store.json'); // In this file is our json object
if(isset($_GET['getAllLikes'])) {
echo $data;
}
if(isset($_POST['imageId']))
{
$jsonObj = json_decode($data);
$likedImg = null;
foreach($jsonObj->images as $v)
{
if($v->imageId == $_POST['imageId'])
{
$v->likes++;
$likedImg = $v;
}
}
file_put_contents('store.json', json_encode($jsonObj));
echo json_encode($likedImg);
}
I am trying to render an image using php for my website that will dynamically display images straight from the Google Places API (Reference https://developers.google.com/places/web-service/photos?hl=en)
The image source looks like the following example:
https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=CnRtAAAATLZNl354RwP_9UKbQ_5Psy40texXePv4oAlgP4qNEkdIrkyse7rPXYGd9D_Uj1rVsQdWT4oRz4QrYAJNpFX7rzqqMlZw2h2E2y5IKMUZ7ouD_SlcHxYq1yL4KbKUv3qtWgTK0A6QbGh87GB3sscrHRIQiG2RrmU_jF4tENr9wGS_YxoUSSDrYjWmrNfeEHSGSc3FyhNLlBU&key=API_KEY
If you visit this URL via your browser it will render an image and this is no longer the URL you see.
My issue is that when viewing the page source, this is exactly the image source URL you see which is bad because my key is then publicized. What is the proper way to render images while keeping my key private? I have searched the API and the web for this but to no avail. I did see some tricks using file_get_contents and file_put_contents but my web host does not allow that. Finally, saving the images is against the api rules so that is not an option.
Any tips would be appreciated. Thanks in advance.
You may send a HEAD-request to the particular URL and extract the content of the Location-header:
<?php
$context = stream_context_create(array('http' =>array('method'=>'HEAD')));
$fp = fopen('desiredPlacesApiImgUrl', 'rb', false, $context);
$meta = stream_get_meta_data($fp);
if(isset($meta['wrapper_data'])){
$location=preg_grep('#^\s*Location:#',$meta['wrapper_data']);
if(count($location)){
$imgUrl=trim(preg_replace('#^Location:#i','',reset($location)));
die($imgUrl);//the desired img-url
}
}
fclose($fp);
?>
But when file_get_contents isn't allowed on your server I'm afraid fopen also isn't allowed for external URLs.
Another option: use the Maps-Javascript-API, request the place and the response should contain the desired URL (without using any key).
Demo:
function loadPlacePhotos() {
var photos = document.querySelectorAll('img[data-place]'),
service = new google.maps.places
.PlacesService(document.createElement('div'));
for (var i = 0; i < photos.length; ++i) {
(function(photo) {
service.getDetails({
placeId: photo.getAttribute('data-place')
}, function(r) {
if (r.photos.length) {
google.maps.event.addDomListener(photo, 'click', function() {
photo.setAttribute('src', r.photos[0].getUrl({
maxHeight: 100
}));
photo.style.visibility = 'visible';
if (r.photos.length > 1) {
r.photos.push(r.photos.shift());
photo.setAttribute('title', 'click to see next photo');
photo.style.cursor = 'pointer';
} else {
google.maps.event.clearListeners(photo, 'click');
}
});
google.maps.event.trigger(photo, 'click');
}
});
}(photos[i]));
}
}
body::before {
content: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-white2.png);
}
img[data-place] {
visibility: hidden;
display: block;
}
<ul>
<li>
Google: Mountain View
<img data-place="ChIJj61dQgK6j4AR4GeTYWZsKWw" />
</li>
<li>
Google: Sydney
<img data-place="ChIJN1t_tDeuEmsRUsoyG83frY4" />
</li>
<li>
Google: Berlin
<img data-place="ChIJReW1rcRRqEcRaY3CuKBdqZE" />
</li>
</ul>
<script defer src="https://maps.googleapis.com/maps/api/js?v=3&libraries=places&callback=loadPlacePhotos"></script>
The demo uses a custom attribute for images data-place which will be assigned to a placeId of a particular place. It parses these images, requests the photos and displays them(when there ar more than 1 photo the user can switch between the photos by clicking on the image )
However, it must not be a problem when your key is visible, set the allowed referers for your (browser)-key and you can use the key without a risk on your own domain.
I know this may look strange but it happened to me many times.
I'm building a website, and everytime I use ajax, i choose POST as method, and to call datas in php file I use $_POST.
At first it works... but after a few days, all scripts using ajax don't work anymore, then I tried to remplace $_POST to $_GET, but ajax method is still always POST.
and after some days again scripts don't work and i remplace get to post... I don't want to get these errors again so I want to know why i had to remplace those methodes in php files.
this is example of the JS code
$(".add-category").click(function(e) {
e.preventDefault();
var $this = $(this);
$(".cats").append('<div class="load" style="margin:auto"><i class="fa fa-spinner fa-spin"></i></div>');
$.ajax({
method : "POST",
url : $this.data("url"),
data : {
cat : $this.prev().val()
},
success : function(data){
$('.load').remove();
$(".cats").append(data);
}
});
});
and this is its php file
<?php
require_once "../../core/Database.php";
require_once "../../core/functions.php";
Database::connect();
if(isset($_GET["cat"]) && strlen($_GET["cat"]) > 0 ){
Database::query("INSERT INTO categories(title_category) VALUES(?)",[$_GET["cat"]]);
$req = Database::query("SELECT * FROM categories ORDER BY id_category DESC");
$cat = $req->fetch();
echo '
<div class="gray cat">'.$cat->title_category.'
<i class="fa fa-trash"></i>
</div>
';
}
Thanks
I am currently working in wordpress and I have a link that is supposed to play a wav file depending on the title of the post. So if the post title is 'one' then it should play one.wav from the uploads folder. However, the sound file on every post only plays the most current posts title. So if I added a post called two and then a post called one, both posts will play one.wav.
Here's the code:
HTML
<span id="dummy"></span>
<a class="playSound" onclick="playSound();" href="#">
<i class="fa fa-volume-up"></i>
</a>
JQuery
function playSound() {
$.ajax({
url: 'sound.php',
data: "getSound",
type: "GET",
datatype: "html",
success: function(data) {
document.getElementById("dummy").innerHTML= "<embed src=\""+data+"\" hidden=\"true\" autostart=\"true\"loop=\"false\" />";
}
});
}
and the PHP
<?php
require('./wp-blog-header.php');
if(isset($_GET['getSound'])) {
$file='wp-content/uploads/2015/wav/' . get_the_title() . '.wav';
echo $file;
}
?>
I assume get_the_title() is the proper call but at this point I am not so sure. I have tried all the other call functions but still no luck. I assume at this point is has to do with the loading of the page and storing the initial posts title but i am just lost at this point.
<?php
$sound_query = new WP_Query();
if ($sound_query->have_posts()):
while ($sound_query->have_posts()):
$sound_query->the_post();
?>
<script>
function playSound() {
document.getElementById("dummy").innerHTML= "<embed src='wp-content/uploads/2015/wav/<?php echo get_the_title() ?>.wav' />";
}
</script>
<?php
endwhile;
endif;
wp_reset_postdata();
?>
Change your sound.php file code like
<?php
require('./wp-blog-header.php');
global $post;
setup_postdata( $post );
if(isset($_GET['getSound'])) {
$file='wp-content/uploads/2015/wav/' . get_the_title( get_the_ID() ) . '.wav';
echo $file;
}
?>
You can simply get ride of your second php code and just use javascript:
function playSound() {
document.getElementById("dummy").innerHTML= "<embed src='wp-content/uploads/2015/wav/<?php echo get_the_title( get_the_ID() ) ?>.wav' />";
}
Everything is disjointed. The JS file doesn't know what post you are trying to target, and hence the sound.php file doesn't know either.
Pass the post ID to the JS file and then pass it to the sound.php file, then extract the post from that.
Also, try not using the post title for such things, use the ID as the post title and post name can be changed.
Example:
HTML
<a class="playSound" onclick="playSound(<?php echo $post->ID; ?>);" href="#">
<i class="fa fa-volume-up"></i>
</a>
JS
function playSound(postID) {
$.ajax({
url: 'sound.php',
data: data: {"postID": postID
type: "GET",
datatype: "html",
success: function(data) {
//Function here
})
}
PHP
if(isset($_GET['postID'])) {
$file='wp-content/uploads/2015/wav/' . $_GET['postID'] . '.wav';
echo $file;
}
Or something similar to that anyway.
Scenario: I have a view with a twitter bootstrap thumbnail grid that shows the countries. When the user clicks one image, it is supposed to show the cities related to that country, in the same grid (screen).
Technical: First I fill the dataProvider with countries, and then I should send a ajax request with the country id to my controller where it queries the database for cities related to that country and sends the new dataProvider, back to the view where it updates the same thumbnail dataProvider with new data.
Question: How do I do this?
Here is my code:
view with thumbnail declaration (name of the view: _detail)
<?php
$this->widget('bootstrap.widgets.TbThumbnails', array(
'id' => 'detailThumbnails',
'dataProvider' => $dataprov,
'template' => "{items}\n{pager}",
'itemView' => '_thumb',
));
?>
view called in thumbnail "itemView" property (name of the view: _thumb)
<?php
require_once '_detail.php';
?>
<li class="span3">
<a href="#" class="<?php echo "thumbnail".$data['id'] ?>" rel="tooltip" data-title=" <?php echo "Clicar.."; ?>">
<img src="<?php echo Yii::app()->getBaseUrl() . $data['photo'] ?>" alt="">
<a href=
"
<?php
echo $className;
echo $this->createUrl(get_class($data).'/view', array('id' => $data['id']));
?>
"
>
<?php
echo $data['name'].$data['id'];
?>
</a>
<?php
Yii::app()->clientScript->registerScript('thumbClick'.$data['id'],'
$(".thumbnail'.$data['id'].'").click(function(){
var request = $.ajax({
data: {
id : '.$data['id'].'
},
type: "post",
url:"'.Yii::app()->createAbsoluteUrl("tripDetail/getCities").'",
error: function(response, error)
{
alert("Error: " + response + " : " + error);
},
});
$(".thumbnail'.$data['id'].'").ajaxSuccess(function() {
$.fn.yiiListView.update("detailThumbnails");
});
});
');
?>
</a>
</li>
In case of success i need to update the same dataProvider, which is in the view named _detail, hence the require_once. What iam trying to do is pass the data from controller(below) in json and decode here. But i don't know how to build a new data provider from the json response, and dont know either if the encode is properly made. Is it????
controller (just some functions)
public function actionCreate()
{
$session = new CHttpSession;
$session->open();
if(isset($_SESSION['mySession']))
{
$data = $_SESSION['mySession'];
if ($data)
{
if(!isset($_GET['ajax']))
{
$dataprov = new CActiveDataProvider("Country");
$this->render('create',
array(
'dat'=>$data,
'dataprov'=>$dataprov
)
);
}
}
}
}
public function actionGetCities()
{
if(isset($_POST['id']))
{
$cityId = $_POST['id'];
$dataProvider = $this->getCitiesFromDb($cityId);
echo $this->renderPartial('_detail',array('dataprov'=> $dataProvider),true,true);
}
}
public function getCitiesFromDb($cityId)
{
$criteria = new CDbCriteria;
$criteria->select = "*";
$criteria->condition = "b4_Country_id = " . $cityId;
$dataProv = new CActiveDataProvider('City',
array('criteria'=>$criteria));
return $dataProv;
}
If this is not the right way to do this, please let me know
You are mixing Server Side Code and Client side code.
Server Side Code
This code resides on server and upon request it gets executed to provide the valid output to the client. Once it is done it does not maintains any connection with the client
Client Side code
Once request is sent to server client waits for response from server and receives anything sent from server. Once done it disconnects from server until further requests made by user or scripts.
What you did here is <?php$json = CJSON::decode(data)?> php tags are serverside thing and they can not be populated because they appear on client side as in your code. Consider following
If you successfully made the AJAX request you better try changing datatype of Ajax request. I guess you are half way there but you do not know how to decode the JSON received. you can use 'dataType'=>'json' in your ajax request. for more details see Updating fields with Ajax and Json
Hopes this makes life easier
As for update part you can do something like create page and call it via renderpartial and return HTML to your view
public function actionGetCities()
{
if(isset($_POST['id']))
{
$cityId = $_POST['id'];
$dataProvider = $this->getCitiesFromDb($cityId);
echo $this->renderPartial('updateView',array('dataprovider'=> $dataProvider),true,true);//see documentation for third and fourth parameter and change if you like
}
}
and in your view you can just update the div that initially have the orignal grid so no need to use json format.
updateView
<?php
$this->widget('bootstrap.widgets.TbThumbnails', array(
'id' => 'detailThumbnails',
'dataProvider' => $dataProvider,
'template' => "{items}\n{pager}",
'itemView' => '_thumb',
));
?>
Note:
This code is not tested and is given for an idea only.
Ok, yesterday i fixed the problem that was in the jquery. The html generated was right but was not being inserted, when the image refreshed, and then, a little light turned on:
Yii::app()->clientScript->registerScript('thumbClick'.$data['id'],'
$(".thumbnail'.$data['id'].'").click(function(){
var request = $.ajax({
data: {
id : '.$data['id'].'
},
type: "post",
success: function(data) {
$("#detailThumbnails").html(data);
},
url:"'.Yii::app()->createAbsoluteUrl("tripDetail/getCities").'",
error: function(response, error)
{
alert("Error: " + response + " : " + error);
},
});
});
');
The part of the code that says "sucess: "
Thank you very much for all the help you people gave me, specially bool.dev. Your help was precious.