Easiest way to display specific value from reddit comments .json file? - json

Is there a simple way to display on my website a specific value, for example "Gonna make this my new alarm ringtone" from following reddit comments .json file: https://www.reddit.com/r/funny/comments/mi0lic/.json
I've found a simple php script that works with reddit user .json files:
... $content = file_get_contents("https://www.reddit.com/user/joshfolgado/about.json");
$result = json_decode($content);
print_r( $result->data->subreddit->title ); ...
But I can't make this work using the comments .json file:
... $content = file_get_contents("https://www.reddit.com/r/funny/comments/mi0lic/.json");
$result = json_decode($content);
print_r( $result->data->children->data->title ); ...
Any other simple script that does the job is also welcome.

The issue can be found here:
print_r( $result->data->children->data->title ); ...
$result->data->children is an Array holding all the comments returned by the API.
We should 'search' all those comments (in your example, it's just 1) for the desired object.
Consider the following code example we're I've used array_filter to custom filter the objects found in $result->data->children array.
<?php
// Search string
$search = 'Gonna make this my new alarm ringtone';
// Get json using CURL
$json = getJson('t3_mi0lic');
// Search ->children
$res = array_filter($json->data->children, function ($child) use ($search) {
// Include if ->data->title qeuals search
return $child->data->title === $search;
});
// Show result
var_dump($res);
// Get JSON by $userId
function getJson($userId) {
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.reddit.com/api/info/?id=' . $userId,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)'
));
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response);
}

Related

why do i get an error in this json request?

this is my function:
function transaction_create($wallet_id, $passphrase, $payment_address, $payment_amount, $metadata = array()) {
$api_host = "";
$api_user = "";
$api_pass = "";
$api_url = "/v2/";
$api_endpoint = "wallets/" . $wallet_id . "/transactions";
// post body
$transaction = array(
"passphrase" => $passphrase,
"payments" => array(
"address" => $payment_address,
"amount" => array(
"quantity" => $payment_amount,
"unit" => "lovelace"
),
),
"metadata" => $metadata,
"time_to_live" => array(
"quantity" => 10,
"unit" => "second"
)
);
$curl = curl_init('https://' . $api_user . ":". $api_pass . "#". $api_host . $api_url . $api_endpoint);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($transaction));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$api_response = curl_exec($curl);
curl_close($curl);
// $api_response - available data from the API request
return $api_response;
}
this is the docs about the api:
https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/postTransaction
the part that is giving me the problem is formatting the "payments" array. the results of my function are:
"{"code":"bad_request","message":"Error in $.payments: parsing
NonEmpty failed, expected Array, but encountered Object"}"
then if i create a class and make the "payments" into a real object, i get the opposite error, it wants an array not an object... ??!!?? im confused.
From the doc, Amount is an object, not an array - Also, so is Time to Live. PHP seems to have some gotcha's when it comes to JSON - my recommendation would be to try to capture the post as it is presented, and make sure arrays are [] and objects are {}.

WordPress Cron Job import posts

I am building a site to import products from an JSON feed, and then display them as posts in my site.
I am using a cron job to run an import every day at 3am, but I have a question regarding the setup of it all.
Would it be good practice to import the feed, create posts based on the feed and then populate the posts on the site?
To remove duplicates I would run a DB check for the product ID and skip those that are already created.
I am really new to cron and dynamically creating posts so I am not sure if this is the best way to go about it.
I solved it by adding an AJAX handler to my functions.php, fetch the jobs through a curl request and then looping through the feed inserting new posts to DB and updating already existing posts.
//CURL request to fetch feed when getting AJAX call
function import_feed() {
$url = "http://url-to-jsonfeed.com";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$data = json_decode($response, true);
create_posts($data);
wp_die();
}
add_action('wp_ajax_import_feed', 'import_feed');
//Loop through JSON data and create post
function create_posts($jsonfeed) {
$data = $jsonfeed['Report'];
if (!empty($data) ) {
foreach ($data as $entry) {
//Set post data before creating post
$post_data = array(
'post_title' => $entry['Entry_Title'],
'post_name' => $entry['EntryID'],
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'entries'
);
if (get_page_by_title($post_data['post_title'], 'entries') == null && empty(get_posts(array('post_type' => 'entries', 'name' => $post_data['post_name'])))) {
wp_insert_post($post_data, $wp_error);
} else if (!empty(get_posts(array('post_type' => 'entries', 'name' => $post_data['post_name'])))) {
$post = get_posts(array('post_type' => 'entries', 'name' => $post_data['post_name']));
$post_id = $post[0]->ID;
$post_data['ID'] = $post_id;
wp_update_post($post_data, $wp_error);
}
}
}
}

Json returned from recaptcha is ... bad

When doing
$response = file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $context);
$result = json_decode($response);
The response is
)]}'
["uvresp","03AJpayVHarkP_b40i5...stuff...VOrIy6m3ws",1,120]
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
The )]}' breaks things. I have no idea where that is coming from.
$g_recaptcha_response looks fine to me (what I am sending to google to verify).
The function to verify recaptcha
function verify_recaptcha ($g_recaptcha_response, $remote_address) {
# Verify captcha
$post_data = http_build_query(
array(
'secret' => 'secret',
'response' => $g_recaptcha_response,
'remoteip' => $remote_address
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $post_data
)
);
$context = stream_context_create($opts);
$response = file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, $context);
$result = json_decode($response);
return $result->success;
}
Thanks.
Ok my bad. The above code works, I had a problem further downstream (query was trying to use a column that did not exist).

Use JSON in Symfony controller

I'm looking for a way to execute a little bit of JSON from my Symfony (2.6 btw) controller, moreover than an other action (post data into database)
In fact, there is an register page with a controller which put data into database and then, redirect user to another page. But i need that my controller execute too a little bit of JSON to use Mailchimp API.
I've found a lot of docs about how to render JSON response, but, it seems to me that it's not what i want to be.
There is my controller
public function registerAction(Request $request)
{
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
/** #var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->get('event_dispatcher');
$user = $userManager->createUser();
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isValid()) {
// Gestion du type d'utilisateur et ajout du role
$user_type = $form->get('user_profile')->get('type')->getData();
$new_role = $this->roles[$user_type];
$event = new FormEvent($form, $request);
$user = $event->getForm()->getData();
$user->addRole($new_role);
$user->getUserProfile()->setEmail($user->getEmail());
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
return $this->render('FOSUserBundle:Registration:register.html.twig', array(
'form' => $form->createView(),
));
}
There is my JSON request
{
"email_address": "$email",
"status": "subscribed",
"merge_fields": {
"FNAME": "$name",
"LNAME": "$lastname",
"DATE": "$date"
}
}
So, how can i do to execute this JSON with this controller ?
Thank you in advance for your help (and sorry for my excellent english)
You probably want to create the JSON from an array rather than try to pass variables. Try:
$data = [
'email_address' => $email,
'status' => 'subscribed',
'merge_fields' => [
'FNAME' => $name,
'LNAME' => $lastname,
'DATE' => $date,
],
];
$json = json_encode($data);
Then I'm assuming this data gets sent to MailChimp in a POST request? If so, you could use Guzzle to send the data to MailChimp:
First add the guzzle dependency in composer by running:
composer require guzzlehttp/guzzle
Then send the data:
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://MAILCHIMP_URL', ['body' => $data]);
To send JSON instead of raw data, do the following:
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://MAILCHIMP_URL', ['json' => $data]);
Depending on the response status, you can then handle the logic afterwards.
You can achieve this also using JsonResponse (Symfony\Component\HttpFoundation\JsonResponse)
use Symfony\Component\HttpFoundation\JsonResponse;
...
// if you know the data to send when creating the response
$data = [
'email_address' => $email,
'status' => 'subscribed',
'merge_fields' => [
'FNAME' => $name,
'LNAME' => $lastname,
'DATE' => $date,
]
];
$response = new JsonResponse($data);
return $response;
More details here https://symfony.com/doc/current/components/http_foundation.html

Yii2: Run a web action in a console controller

Is it possible to run a web action in a console controller?
In a web controller (yii\web\Controller) I have an action which I would like to run as a cron job. But if I try to run it in a console controller (yii\console\Controller):
Yii::$app->runAction('controller/action');
then I receive the following error message:
Error: Unknown command "controller/action".
Run a web action in a console controller:
Yii::$app->controllerNamespace = "app\controllers";
Yii::$app->runAction('controller/action');
Assign controllerNamespace before running the web action from console.
In addition, disable enableCsrfValidation for the web action:
public function beforeAction($action)
{
if ($action->id == 'action') {
$this->enableCsrfValidation = false;
}
return parent::beforeAction($action);
}
The 'action' ID could be replaced with your current web action ID.
Sorry, I did not understand the context of the question.
As #soju says, you should find a way to do it using CURL, but there is a way.
$config = \yii\helpers\ArrayHelper::merge(
require(Yii::getAlias('#common').'/config/main.php'),
require(Yii::getAlias('#common').'/config/main-local.php'),
require(Yii::getAlias('#frontend').'/config/main.php'),
require(Yii::getAlias('#frontend').'/config/main-local.php')
);
$web_application = new \yii\web\Application($config);
$web_application->runAction('/site/index',['param1' => 1,'param2' => 2]);
You should be aware that the controller works with their behaviors, then the AccessControl could prevent the execution
The solution with cURL.
In the web controller have to be disabled the CSRF validation:
public function beforeAction() {
if ($this->action->id == 'export') {
Yii::$app->controller->enableCsrfValidation = false;
}
return true;
}
The cURL commands in the console Controller can look e.g. like this:
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_REFERER => $url,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_COOKIESESSION => true,
CURLOPT_COOKIEJAR => 'curl-cookie.txt',
CURLOPT_COOKIEFILE => '/var/www/yii/frontend/web/tmp',
CURLOPT_CONNECTTIMEOUT => 120,
CURLOPT_TIMEOUT => 120,
CURLOPT_MAXREDIRS => 10,
CURLOPT_USERAGENT => "Dark Secret Ninja/1.0",
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => "LoginForm[username]=".$username.
"&LoginForm[password]=".$password.
"&LoginForm[rememberMe]=1",
CURLOPT_SSL_VERIFYPEER => false,
);
curl_setopt_array( $ch, $options );
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); //get status code
if ( $httpCode != 200 ){
echo "Return code is {$httpCode} \n"
.curl_error($ch);
} else {
echo htmlspecialchars($response);
}
curl_close($ch);