wp_is_post_autosave is not working - facebook

I want to auto publish all articles of my WP blog on Facebook without using any plugin.
I wrote some working code to do that and it's OK... but I also need to invoke this code only when I publish a new article (not for revisions or autosave).
That's the part of my function.php file that you need to see:
add_action( 'save_post', 'koolmind_facebook_post_article',3 );
function koolmind_facebook_post_article( $post_id ) {
/* configuration of facebook params */
....
....
/* end config */
if ( !wp_is_post_revision( $post_id ) && !wp_is_post_autosave( $post_id ) ) {
/* retrieve some data to publish */
/* invoke my code to publish on facebook */
}
}
My code is invoked as soon as I click on "add new article", and an empty draft is sent to my Facebook page.
In add, as soon as I insert a single char on my article body, autosave is triggered and a new post (almost empty) is sent again to facebook.
I just want to block this automatic publishing and send my data to facebook only when I press the PUBLISH button.
Is that possible?
UPDATE
Finally I've found the problem. There was an error inside my fb code.
Problem now is avoiding multiple pubblication when updating my post.
Here's the code now:
add_action('pending_to_publish', 'koolmind_facebook_post_article');
add_action('draft_to_publish', 'koolmind_facebook_post_article');
add_action('new_to_publish', 'koolmind_facebook_post_article');
function koolmind_facebook_post_article( $post_id ) {
require_once 'facebook/facebook.php';
/* some code here */
//verify post is not a revision
if ( !wp_is_post_revision( $post_id ) ) {
$post_title = get_the_title( $post_id );
$post_url = get_permalink( $post_id );
$post_excerpt = get_the_excerpt();
$post_image = 'http://.../default.jpg'; //default image
if( $thumb_id = get_post_thumbnail_id( $post_id ) ){
$image_attributes = wp_get_attachment_image_src( $thumb_id );
$post_image = $image_attributes[0];
}
/* some code here */
}
}
Let me explain the issue:
If I use these 3 hooks I have no problem, but the code is executed before my featured image is stored into the database, so $post_image is always equals to the default image.
If I use publish_post hook instead, featured image is set properly (maybe because this hook is called after all data have been saved), but I cannot avoid data sending to Facebook if I update my post (wp_is_post_revision seems not to be fired).
Hope you have a good idea... now the code is almost OK! :)

The 'save_post' hook 'Runs after the data is saved to the database'. This means you can do this validation:
//WP hook
//the last parameter 2 means you pass 2 variables to the callback:
//the ID and the post WP object
add_action( 'save_post', 'koolmind_facebook_post_article',3,2 );
//Callback
function koolmind_facebook_post_article( $post_id, $post ) {
// Validation:
//If current WP user has no permissions to edit posts: exit function
if( !current_user_can('edit_post', $post_id) ) return;
//If is doing auto-save: exit function
if( defined('DOING_AUTOSAVE') AND DOING_AUTOSAVE ) return;
//If is doing auto-save via AJAX: exit function
if( defined( 'DOING_AJAX' ) && DOING_AJAX ) return;
//If is a revision or an autosave version or anything else: exit function
if( $post->post_status != 'publish') return;
/* configuration of facebook params */
/* invoke my code to publish on facebook */
}
It worked for me.

Try using:
add_action('publish_post', 'koolmind_facebook_post_article');

Related

WooCommerce pdf attachment to custom email is not working

I am using WooCommerce order status manager plugin for custom order statuses and emails notifications. I have created custom status for paid orders via card pay - card-on-hold.
I have also created custom email which will be triggered when statuses will change from receivet to card-on-hold.
my code is:
add_filter( 'woocommerce_email_attachments', 'attach_manual_pdf_to_email', 10, 3);
function attach_manual_pdf_to_email ( $attachments, $status , $order ) {
$allowed_statuses = array( 'customer_processing_order', 'customer_on_hold_order', 'customer_order_status_email' );
if( isset( $status ) && in_array ( $status, $allowed_statuses ) ) {
$dokument = get_template_directory() . '/woocommerce/emails/attach.pdf';
$attachments = $dokument;
}
return $attachments;
}
Email Ids customer_processing_order and customer_on_hold_order works like a charm.
But customer_order_status_email which is php template for order status manager is not working. It is located in betheme/woocommerce/emails/customer-order-status-email.php and I did also try to move it to same locations where other templates are but that did not help.
Any idea how to make this working please?
okay i did find a solution:
i did use echo '<pre>'; print_r($email->id); echo '</pre>' in template of an email which printed me an email ID. i used this id in my allowed statuses and it is working now.

Displaying a flash message in the Backend using a hook doesn't work somehow

Basically: I want to display a flash message in the BE whenever the user enters a value that is not a valid IPv4. I want to do this in a hook, but just using the code from the Typo3 documentation for flash messages doesn't work there seems to be a major missunderstanding on my side maybe. Here is my code so far:
<?php
namespace Cjk\Icingaconfgen\Hook;
class EvalHook {
function processDatamap_postProcessFieldArray($status, $table, $id, &$fieldArray, &$pObj) {
if (!filter_var($fieldArray[IPv4], FILTER_VALIDATE_IP)){
//here i want to put the flash message code
}
}
}
?>
Using the code from the documentation here:
$message = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class,
'My message text',
'Message Header', // [optional] the header
\TYPO3\CMS\Core\Messaging\FlashMessage::WARNING, // [optional] the severity defaults to \TYPO3\CMS\Core\Messaging\FlashMessage::OK
true // [optional] whether the message should be stored in the session or only in the \TYPO3\CMS\Core\Messaging\FlashMessageQueue object (default is false)
);
with the addition of the line:
$message->render();
doesn't work. What am i missing?
Have you tried adding the FlashMessage to the message queue?
use TYPO3\CMS\Core\Messaging\FlashMessageService;
// ... omitted some use statements
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
//...
$flashMessageService = $this->objectManager->get(lashMessageService::class);
$messageQueue = $flashMessageService->getMessageQueueByIdentifier();
$messageQueue->addMessage($message);
You wouldn't need that part, if you used the flash messages in the Controller.
https://docs.typo3.org/typo3cms/CoreApiReference/ApiOverview/FlashMessages/Index.html

How to define redirect page for protected pages

In a TYPO3 6.1 site, I would like to make the creation of restricted (fe_groups) pages as easy as possible for editors. There's not one single protected area, but several protected pages all over the pagetree.
What I would like to achieve would be that whenever a page has some login behaviour/restriction and no valid fe_user is logged in, there is a redirection to a central login page.
I have found this post
TYPO3 - Redirecting to login page when user is not logged in that refers to the same issue - but the solution requires setting PIDs by hand.
I can hardly believe that such a feature ("set target page for redirections based on access restrictions") is not available. Or does it exist, or is it on a roadmap somewhere? And if not, is there a workaround?
This is indeed a big missing feature in TYPO3. The problem is that because of the way TYPO3 is built it's hard to determine whether a page doesn't exist (404) or access is forbidden (403). I did some further development of an unpublished extension that does the job, see https://github.com/phluzern/adfc_pagenotfound
In readme.txt you will find the configuration that is needed. It is in use with TYPO3 4.7, therefore some used classes may be deprecated or removed in 6.1. If so, fork the project, change them and make some pull requests so I can update it.
The extension makes use of a custom parameter $arPid (access restriction pid). The ID to the page that is access restricted is sent to the login page. Your login form must be able to handle this parameter in order to redirect, see an example here:
https://github.com/phluzern/phzldap/blob/master/pi1/class.tx_phzldap_pi1.php#L133
It might be better to use a redirect_url as it is supported in felogin.
Update
In the meantime, I'm using an improved class with the following features:
If access to page is forbidden, redirect to a login page with the standard redirect_url parameter. This allows a redirect after a successful fe login using EXT:felogin without modifications and also supports speaking URLs.
Redirect to 404 page if page is not found respecting the current language of the site.
The code is as follows:
<?php
use TYPO3\CMS\Core\Utility\GeneralUtility;
class user_pageNotFound {
/**
* Detect language and redirect to 404 error page
*
* #param array $params "currentUrl", "reasonText" and "pageAccessFailureReasons"
* #param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $tsfeObj
*/
public function pageNotFound($params, $tsfeObj) {
/*
* If a non-existing page with a RealURL path was requested (www.mydomain.tld/foobar), a fe_group value for an empty
* key is set:
* $params['pageAccessFailureReasons']['fe_group'][null] = 0;
* This is the reason why the second check was implemented.
*/
if (!empty($params['pageAccessFailureReasons']['fe_group']) && !array_key_exists(null, $params['pageAccessFailureReasons']['fe_group'])) {
// page access failed because of missing permissions
header('HTTP/1.0 403 Forbidden');
$this->initTSFE(1);
/** #var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj */
$cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
$loginUrl = $cObj->typoLink_URL(array(
'parameter' => $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_loginPageID'],
'useCacheHash' => FALSE,
'forceAbsoluteUrl' => TRUE,
'additionalParams' => '&redirect_url=' . $params['currentUrl']
));
TYPO3\CMS\Core\Utility\HttpUtility::redirect($loginUrl);
} else {
// page not found
// get first realurl configuration array (important for multidomain)
$realurlConf = array_shift($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']);
// look for language configuration
foreach ($realurlConf['preVars'] as $conf) {
if ($conf['GETvar'] == 'L') {
foreach ($conf['valueMap'] as $k => $v) {
// if the key is empty (e.g. default language without prefix), break
if (empty($k)) {
continue;
}
// we expect a part like "/de/" in requested url
if (GeneralUtility::isFirstPartOfStr($params['currentUrl'], '/' . $k . '/')) {
$tsfeObj->pageErrorHandler('/index.php?id=' . $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID'] . '&L=' . $v);
}
}
}
}
// handle default language
$tsfeObj->pageErrorHandler('/index.php?id=' . $GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID']);
}
}
/**
* Initializes a TypoScript Frontend necessary for using TypoScript and TypoLink functions
*
* #param int $id
* #param int $typeNum
*/
protected function initTSFE($id = 1, $typeNum = 0) {
\TYPO3\CMS\Frontend\Utility\EidUtility::initTCA();
if (!is_object($GLOBALS['TT'])) {
$GLOBALS['TT'] = new \TYPO3\CMS\Core\TimeTracker\NullTimeTracker;
$GLOBALS['TT']->start();
}
$GLOBALS['TSFE'] = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController', $GLOBALS['TYPO3_CONF_VARS'], $id, $typeNum);
$GLOBALS['TSFE']->sys_page = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
$GLOBALS['TSFE']->sys_page->init(TRUE);
$GLOBALS['TSFE']->connectToDB();
$GLOBALS['TSFE']->initFEuser();
$GLOBALS['TSFE']->determineId();
$GLOBALS['TSFE']->initTemplate();
$GLOBALS['TSFE']->rootLine = $GLOBALS['TSFE']->sys_page->getRootLine($id, '');
$GLOBALS['TSFE']->getConfigArray();
if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('realurl')) {
$rootline = \TYPO3\CMS\Backend\Utility\BackendUtility::BEgetRootLine($id);
$host = \TYPO3\CMS\Backend\Utility\BackendUtility::firstDomainRecord($rootline);
$_SERVER['HTTP_HOST'] = $host;
}
}
}
The only thing you need to configure are the PIDs of the page not found and login pages:
// ID of the page to redirect to if page was not found
$GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_redirectPageID'] = 4690;
// ID of the page to redirect to if current page is access protected
$GLOBALS['TYPO3_CONF_VARS']['FE']['pageNotFound_handling_loginPageID'] = 5404;

Making Register Plus Redux work with Nextend Google Connect

I'm trying to make two popular WordPress plug-ins work well together. Hopefully this question isn't too specific to my setup -- I think enough people use these plug-ins to make it a common issue.
I'm using Register Plus Redex (RPR) to require user registration to be accepted (by admin) before a user can log-in. Alone, this works fine.
I'm also using Nextend Google Connect (NGC) to allow users to log-in with Google. Those also need to be approved before they can log-in.
When NGC creates a new user in the database, it correctly has the "not activated" flag set. However, the user is still logged in. This allows them to see some blog pages that are protected by "Members Only" (another plug-in). I could maybe update Members Only or other areas to avoid this, but I would rather these users see the same behavior a normal user would see, one that just logs in with user/password, not Google. They get a nice "Your account has not been activated yet" message.
RPR has this code to authenticate, I think I need to use it from NGC some way:
public /*.object.*/ function rpr_authenticate( /*.object.*/ $user, /*.string.*/ $username, /*.string.*/ $password) {
if ( !empty($user) && !is_wp_error( $user ) ) {
if ( NULL !== get_role( 'rpr_unverified' ) && in_array( 'rpr_unverified', $user->roles ) ) {
return null;
}
}
return $user;
}
I think this is the section of NGC code I need to modify:
$secure_cookie = is_ssl();
$secure_cookie = apply_filters('secure_signon_cookie', $secure_cookie, array());
global $auth_secure_cookie; // XXX ugly hack to pass this to wp_authenticate_cookie
$auth_secure_cookie = $secure_cookie;
wp_set_auth_cookie($ID, true, $secure_cookie);
$user_info = get_userdata($ID);
do_action('wp_login', $user_info->user_login, $user_info);
do_action('nextend_google_user_logged_in', $ID, $u, $oauth2);
update_user_meta($ID, 'google_profile_picture', 'https://profiles.google.com/s2/photos/profile/' . $u['id']);
The NGC code uses what I think is a "hacked" method of log-in. It doesn't use any of the methods I have seen recommended online, like the new wp_signon or older wp_login functions.
Is what I'm trying to do a major project? If so, is there another combination of plug-ins (or a single one) that will handle the following:
Require users to be logged in to see any pages (what Members Only does)
Require admin to moderate/approve new users (what RPR does)
Support log-in via Facebook, Twitter, and Google (what the Nextend Connect plug-ins do)
Update:
I changed the NGC code to this, and now it doesn't log the user in, but it just leaves them on the log-in page with no error message. I'm not sure how I can add an error message to the default log-in page, everything I find online is related to custom log-in pages.
if ($ID) { // Login
$user_info = get_userdata($ID);
if ( !empty($user_info) && !is_wp_error( $user_info ) ) {
if ( NULL !== get_role( 'rpr_unverified' ) && in_array( 'rpr_unverified', $user_info->roles ) ) {
// TODO - How to add error message to log-in page?
return;
}
}
$secure_cookie = is_ssl();
$secure_cookie = apply_filters('secure_signon_cookie', $secure_cookie, array());
global $auth_secure_cookie; // XXX ugly hack to pass this to wp_authenticate_cookie
$auth_secure_cookie = $secure_cookie;
wp_set_auth_cookie($ID, true, $secure_cookie);
//
do_action('wp_login', $user_info->user_login, $user_info);
do_action('nextend_google_user_logged_in', $ID, $u, $oauth2);
update_user_meta($ID, 'google_profile_picture', 'https://profiles.google.com/s2/photos/profile/' . $u['id']);
}
I'm sure there is a better way to do this, one that will not be undone anytime I update the plug-in, but for now this works for me.
I updated nextend-google-connect.php, part of the Nextend Google Connect plug-in, and changed the Login code (starting around line 230 depending on your version) to this:
if ($ID) { // Login
$user_info = get_userdata($ID);
if ( !empty($user_info) && !is_wp_error( $user_info ) ) {
if ( NULL !== get_role( 'rpr_unverified' ) && in_array( 'rpr_unverified', $user_info->roles ) ) {
wp_redirect('wp-login.php?checkemail=registered');
exit;
}
}
$secure_cookie = is_ssl();
$secure_cookie = apply_filters('secure_signon_cookie', $secure_cookie, array());
global $auth_secure_cookie; // XXX ugly hack to pass this to wp_authenticate_cookie
$auth_secure_cookie = $secure_cookie;
wp_set_auth_cookie($ID, true, $secure_cookie);
do_action('wp_login', $user_info->user_login, $user_info);
do_action('nextend_google_user_logged_in', $ID, $u, $oauth2);
update_user_meta($ID, 'google_profile_picture', 'https://profiles.google.com/s2/photos/profile/' . $u['id']);
}
By redirecting to that special URL, the Redux plug-in already has code to display a nice message to the user letting them know the admin needs to verify the account.

How to fix Zend session incorrect data ('css')

I have coded a simple admin module with ability to paginate records and sort them by some column. And when I sort and then call some other action on the records it should redirect the user back to index page with the same sort parameters as there were before. But after I call the indexAction() with parameters like this /admin/users/index/column/num_orders/order/ASC and then call the toggleActiveAction() I am redirected to page /admin/users/index/column/num_orders/order/CSS.
The same story with .../index/page/2 => .../index/page/css.
Why "CSS"? My session data never used in other context than you see below.
In my bootstrap I have the following:
protected function _initSession()
{
Zend_Session::start();
}
Controller init():
...
$this->_session = new Zend_Session_Namespace('Admin_Users');
...
I have a following function in my controller:
public function redirectToIndex()
{
$options = array();
if (isset($this->_session->curPage) && $this->_session->curPage != 1)
$options['page'] = $this->_session->curPage;
if (isset($this->_session->curColumn) && $this->_session->curColumn)
$options['column'] = $this->_session->curColumn;
if (isset($this->_session->curOrder) && $this->_session->curOrder)
$options['order'] = $this->_session->curOrder;
$this->_helper->redirector('index', 'users', 'admin', $options);
}
In index action:
$curColumn = $this->_getParam('column', '');
$curOrder = strtoupper($this->_getParam('order', ''));
$page = $this->_getParam('page', 1);
...
$this->_session->curPage = $page;
$this->_session->curColumn = $curColumn;
$this->_session->curOrder = $curOrder;
Then in toggleActiveAction() I call
$this->redirectToIndex();
I guess there is a unexisted css file on your page (on js or img) which is handled with Zend Framewok froncontroller. Youd should enable log for all requests that are handled with ZF and you will find there a request like "/theme/supersite/css/thisFileNotExists.css" (or similar :)