How do I connect to external API from Magento - soap

I am looking for some assistance in creating an API based module to push customer information out of Magento into a Third party loyalty program.
So far I have created a basic module but cannot find any good information on creating API based modules in Magento and could really do with some advice please...
I need to somehow hook into the Checkout success page in Magneto and add a form the will POST the customers information (name, address etc) to a third party loyalty program. I also need to be able to login to complete the billing information etc...
Does anyone know of any handy tutorials or documentation for such an implementation?
So far I have setup an API user with the appropriate roles. I have also created a very basic module for test purpses but browsing to the file I get a 404 error
apitest.php
<?php
$proxy = new SoapClient('http://mysite.com/api/?wsdl'); //edit the address and put the url to your magento here
$sessionId = $proxy->login('######', '#######'); // put in the info for your user here
echo "Login ID : $sessionId";
$result = $proxy->call($sessionId, 'Mymodule.testConnection', array('param1' => ' This string was sent from soap client'));
echo $result;
Objectmodel/api.php
<?php
class MyModule_MyModule_Model_ObjectModel_Api extends Mage_Api_Model_Resource_Abstract
{
public function testConnection($arg)
{
return "Hello World! My argument is : " . $arg;
}
}
I followed the example from here for getting a basic 'Hello world' module up and running if anyone could assist me with getting the correct setup I would be grateful

Instead of connect magento API you can create customer like this.
define('INCLUDE_PATH', '/var/www/QA/mojostage/app/');
define('INCLUDE_FILE', 'Mage.php');
Mage::app();
$customer = Mage::getModel('customer/customer');
$customer->setWebsiteId($wesite_id);
$customer->loadByEmail($customer_email);
/*
* Check if the email exist on the system.
* If YES, it will not create a user account.
*/
if (!$customer->getId()) {
//setting data such as email, firstname, lastname, and password
$customer->setEmail($customer_email);
$customer->setTaxvat($value['cus_vatnumber'])
->setCreatedAt($date1)
->setDob($value['date_of_birth'])
->setGroupId($cus_group_id)
->setConfirmation($is_active)
->setCreatedIn('Admin')
->setStoreId($store_id)
->setWebsiteId($wesite_id)
->setEntityId($value['cus_id']);
$customer->setFirstname($customer_fname);
$customer->setLastname($customer_lname);
$customer->setPassword($value['password']);
$subscriber = Mage::getModel('newsletter/subscriber');
$subscriber->setStoreId($store_id)
->setCustomerId($value['cus_id'])
->setSubscriberEmail($customer_email)
->setSubscriberStatus($value['cus_spam'])
->setSubscriberConfirmCode($subscriber->randomSequence());
}
//the save the data and send the new account email.
$customer->save();
$subscriber->save();

Related

Facebook Friend List Import using fboauth, see for local account and display using views

I am using fboauth for enabling login with facebook for the website. Here is an overview of how I achieve the functionality:
When the user clicks on the facebook login button on the website, he or she is taken to a facebook login page. After logging in with facebook, the user is taken to the app authorization page where the user asks for permission to connect with the app. Once necessary permissions are granted, a local account (account at my website) is automatically created for the user and the user is brought back to a welcome page to set password. The user won't even have to verify their email address. On subsequent visits, when the user clicks on the login link, he/she is taken to the same facebook login page where they supply their login credentials. On successful login, they are brought back to the website. So far, everything works fine with the fboauth module.
What I am trying to achieve now is a functionality similar to what is found with the fbconnect module. The user is provided with a block/page where the user can import the list of his friends who has authorized with the app, and see the links to their local accounts (accounts at the website). How to achieve this functionality? The fboauth module has its own API which can be utilized. Here is what I already have, written using the API of fboauth.
<?php
module_load_include('inc', 'fboauth', 'includes/fboauth.fboauth');
module_load_include('module', 'fboauth', 'fboauth');
module_load_include('php', 'fboauth', fboauth.api');
module_load_include('inc', 'fboauth', 'includes/fboauth.field');
module_load_include('inc', 'fboauth', 'includes/fboauth.pages');
module_load_include('inc', 'fboauth', 'includes/fboauth.profile');
/**
* Implements hook_menu().
*/
function mymodule_menu() {
$items['my-friends'] = array(
'title' => t('Your Friends'),
'page callback' => 'friend_import',
'access callback' => TRUE;
);
return $items;
}
function friend_import() {
$result = fboauth_graph_query('me/friends?fields=id', $access_token);
drupal_set_message(t('Import complete!'));
$accounts = array();
$output = "";
foreach($result->data as $fbuid){
$accounts[] = user_load(fboauth_uid_load($fbuid->id));
$output = l($account->name, "/user/" . $account->uid);
}
dpm($accounts);
return $output;
}
This will import all the friends of a user who have authenticated for the app as an object into $result (having name and user id). However, what I am finding it difficult is to display those names with the user's corresponding local accounts (accounts at the website). This is because of my lack of knowledge in php. What I am looking for is here is the exact lines of code that can be inserted after $result recieves its value so that the names of the users are displayed along with the links to their profile pages at the website.
Ok, so, if you look at the fbconnect module, you will see that there is a table that contains both the fid and uid (FB's and Drupal's). There is also a function you can user, to save you from the work of writing the query yourself:
/**
* Load a Drupal User ID given a Facebook ID.
*/
function fboauth_uid_load($fbid) {
$result = db_query("SELECT uid FROM {fboauth_users} WHERE fbid = :fbid", array(':fbid' => $fbid));
$uid = $result->fetchField();
return $uid ? (int) $uid : FALSE;
}
So, in order to get all friends, you would first need to call the the function that returns user's friends in FB:
$result = fboauth_graph_query('me/friends?fields=id', $access_token);
Then, iterate through that $result and get the local data:
$accounts = array();
foreach($result->data as $fbuid){
$accounts[] = user_load(fboauth_uid_load($fbuid->id));
}
So far, I think you had already figured this out.
Next thing we do, depends on how you want the module to behave. If you need a custom page, with an url, implement hook_menu to create that page:
/**
* Implements hook_menu().
*/
function mymodule_menu() {
$items = array();
$items['desired/path'] = array(
'title' => t('My friends'),
'page callback' => 'fb_friends', <-- This function you need to create now
....
);
function fb_friends() {
$result = fboauth_graph_query('me/friends?fields=id', $access_token);
$accounts = array();
$output = "";
foreach($result->data as $fbuid){
$accounts[] = user_load(fboauth_uid_load($fbuid->id);
$output .= l($account->name, "/user/" . $account->uid) . </br>;
}
return $output;
}
For better formatting, instead of building the $output yourself, you would call theme_table, that does it for you: https://api.drupal.org/api/drupal/includes!theme.inc/function/theme_table/7
Lastly, I recommend saving the relationships to a user and his friends in a local table, so next time you don't have to go to FB. I think you can take it from the example above. If your problem is showing the friends, it will do, although not very efficient because of going to FB everytime. Hope it helps.
You need either a user id or name or email to match Drupal's corresponding fields. These three fields are unique for a Drupal site. Unless the query to FB return any of those, you won't be able to map a FB user to a Drupal user.
Provided that the name or the user id are the same for drupal app, you can do:
$output = "";
foreach ($result as $u) {
$output .= $u->name , "<br>"; //or $u->id for the id
}
return $output;
This will work if A) $result contains a list of objects, B) Those are the exact field names.
The other issue is that if you want a custom page with the output, you need to implement the hook_menu so you can provide such custom page in your module.
I recommend you install the Devel module for easily inspection your data. After you install it and enable it, just call dsm($result) from your code, so you have a nice view of what is in the $result variable.
And before actually building that into a module, try simply adding a basic Drupal page, set the format to PHP and write that code, so you can test easily and then move that into the module.
So to recap, the first thing to do is to find out what comes in that variable and in which structure. Then, if any of those fields have the same value for the local users, just write the hook_menu and provide a custom page within your module.
Provided that you have, say, the user id (Drupal's Id) you can build a link to the user account by printing $output .= '' . $name . '<br>'; and then return $output;
If you give me the $result content here, I might come up with a better solution.

ejabberd: Saving of roster not working with external Authentication Script enabled

I have successfully configured an ejabberd server with an extauth script (perl).
It is working correctly and only allowing users from my mysql DB.
But following features are not working anymore: roster management, adding users to rosters, authorization of users (for adding them to the roster)
With the internal auth it works. Both times ejabberd is configured to use the internal amnesia db.
Please help me figure out, why it is not working with extauth enabled. Do I have to write my own methods in the extauth script? (That I don't really want...)
So after doing some research on my problem, I think that switching to the external authentication will not support roster management.
What I ended up doing is swichting back to internal authentication and using mod_admin_extra to add users and update passwords with this php script:
<?php
class Jabber
{
public static function registerAndAddToSharedRoster($userId, $sessionToken)
{
$url = "http://localhost:5280/rest";
$register = "register $userId jabber.YOUR_DOMAIN.com $sessionToken";
sendRESTRequest($url, $register);
$sharedRoster = "srg_user_add $userId jabber.YOUR_DOMAIN.com shared jabber.YOUR_DOMAIN.com";
sendRESTRequest($url, $sharedRoster);
}
public static function updatePassword($userId, $newPassword)
{
$url = "http://localhost:5280/rest";
$register = "change_password $userId jabber.YOUR_DOMAIN.com $newPassword";
sendRESTRequest($url, $register);
}
}
function sendRESTRequest ($url, $request)
{
// Create a stream context so that we can POST the REST request to $url
$context = stream_context_create (array ('http' => array ('method' => 'POST'
,'header' => "Host: localhost:5280\nContent-Type: text/html; charset=utf-8\nContent-Length: ".strlen($request)
,'content' => $request)));
$result = file_get_contents($url, false, $context);
return $result;
}
?>
Hope this helps someone!
This answer is late but it could help someone:
Contrary to #ben-marten's answer, Switching to the external authentication does support roster management.
When you add someone to the roster, ejabberd is 'calling' the isuser operation - check if it’s a valid user - you have to provide that method in the script: see ejabberd Developers Guide - External Authentication
I ignored that operation, and I could not add a user to the roster.
For other script examples see Authentication Scripts

Where to put the business logic in a magento module for an email form?

I'm new to magento and I'm trying to create a module for an email form.
In classic MVC I would send the request to the Controller, but in Magento a controller is only responsible for one URL. So when I want to put my email form on the productpage I cant use the controller, is that right?
I inlcude my block element via layout xml in the productpage. So I have to validate my form und send the email in the class of my block element? Or would I have to write one or more helpers for that?
What is the magento way?
Thanks a lot. Sorry if my question is lame, but I'm a beginner and I want to learn the right way and I have seen so much tutorials with the wrong one.
Just while submitting the form give action to controller like:
<?php echo Mage::getUrl()?>bpartner/index/mailbpartner
bpartner your module name
Index your controller name
mailbpartner your function in INDEX NAMED CONTROLLER FILE.
Get all details through POST and send mail like below + redirect with success
$to = "abc#abc.com";
$dt = date('d-m-Y');
$subject = "Become A Partner Details on date $dt";
$mail = new Zend_Mail('utf-8');
$mail->setBodyHtml($message)
->setFrom($data['email'], $data['firstname'])
->addTo($to, 'Site Admin')
->setSubject($subject);
try {
$mail->send();
Mage::getSingleton('core/session')->addSuccess('Mail sent successfully. We will contact you shortly');
}
catch(Exception $e) {
Mage::getSingleton('core/session')->addError('Unable to send email.');
}
$this->_redirect('bpartner');
Some above data are POST DATA which is self understandable

how to send files as attachment in email in magento for downloadable products?

I am new to Magento. I am working on a web site which is selling downloadable products.
My client want purchased products should be sent via email in attachment?
Currently, I am developing in localhost so I am not sure whether magneto actually send product files in email or not?
Should I need to enable any option for that in configuration?
If you want to develop this at your localhost keep in mind, that you have to set up mail server or use some solutions from community like below link, to send it by gmail and other:
https://www.magentocommerce.com/magento-connect/smtp-pro-email-free-custom-smtp-email.html
You also can just configure your server to save mails without sending.
So you'll be able to review it.
Good article about how to send downloadable by email here:
https://magento.stackexchange.com/questions/49511/how-can-i-get-only-the-downloadable-product-url-in-email-template
But!!! keep in mind that the latest Magento use queue to send email (which runs by cron), so if you have such a distribution (for example 1.9+) you need to adjust code which you have from link above.
Here istwo solutions for this case:
Disable adding email to queue after order.
Just comment this part of code in "Mage_Core_Model_Email_Template"'s "send()" method:
// if ($this->hasQueue() && $this->getQueue() instanceof Mage_Core_Model_Email_Queue) {
/** #var $emailQueue Mage_Core_Model_Email_Queue */
/* $emailQueue = $this->getQueue();
$emailQueue->clearRecipients();
$emailQueue->setMessageBody($text);
$emailQueue->setMessageParameters(array(
'subject' => $subject,
'return_path_email' => $returnPathEmail,
'is_plain' => $this->isPlain(),
'from_email' => $this->getSenderEmail(),
'from_name' => $this->getSenderName(),
'reply_to' => $this->getMail()->getReplyTo(),
'return_to' => $this->getMail()->getReturnPath(),
))
->addRecipients($emails, $names, Mage_Core_Model_Email_Queue::EMAIL_TYPE_TO)
->addRecipients($this->_bccEmails, array(), Mage_Core_Model_Email_Queue::EMAIL_TYPE_BCC);
$emailQueue->addMessageToQueue();
return true;
}*/
So emails will be sent immediately (be aware, that if you have very big turnover with spikes it can create performance issue)
Second way is to save full path of attachment to table "core_email_queue" field - "message_parameters". You can do it adding url to array of argument here $emailQueue->setMessageParameters( in code above.
After that you can handle it in "Mage_Core_Model_Email_Queue"'s "send()" method
using standard "Zend Mail"'s method - "createAttachment()". Below link provides deeper explanation of this part.
https://magento.stackexchange.com/questions/9652/magento-send-file-attachements-in-emails
Hope it will help sombody.
Have a good day!!!

Sending e-mail programmatically in Magento is failing

Why is there nowhere in the Configuration/System/Mail Sending Settings to specify a user name and password for your smtp server?
To get around this, do you need to make the changes to getMail() outlined in this post:
http://www.magentocommerce.com/boards/viewthread/1073/P30/
I want to do something very simple:
- create an e-mail template
- do not have to make reference to that template in any config files.
- programmatically send an e-mail using the template defined above
- supply values to replace any tags in the template
- supply recipient e-mail addresses
- supply other bits, like a from address
So first step - create a template.
- In Confguration/Transactional Emails I believe I am supposed to see a list of templates. I see nothing. But if I add a new template, I can select from a list of templates.
- Give template a name of "Bob".
- Add a few vars to the template:
myvar1={{var myvar1}}
myvar2={{var myvar2}}
- Save the template; it is given an Id of 1.
Now send the e-mail programmatically from a controller action:
- No need to make change to LINEEND in Mime.php as it is already set to \n in version 1.4.2.0
- Make changes to getMail() in Template.php as specified in this post: http://www.magentocommerce.com/boards/viewthread/1073/P30/
- Write code in the controller action to send the e-mail:
This returns nothing:
$emailTemplate = Mage::getModel('core/email_template')->loadDefault('no matter what goes here emailTemplate is not set');
This does return an email template:
$emailTemplate = Mage::getModel('core/email_template')->loadByCode('Bob');
but the call to send below fails:
$emailTemplate->setSenderEmail('sent#byme.com');
$emailTemplate->setSenderName('Steve');
$emailTemplateVariables = array();
$emailTemplateVariables['myvar1'] = 'TestValue1';
$emailTemplateVariables['myvar2'] = 'TestValue2';
// $processedTemplate = $emailTemplate->getProcessedTemplate($emailTemplateVariables); -- this returns nothing
$emailTemplate->send('thisisme#mydomain.com','John', $emailTemplateVariables);
In the system.log I get the warning below, and no e-mail ever arrives.
Warning: stream_socket_enable_crypto() [<a href='streams.crypto'>streams.crypto</a>]: this stream does not support SSL/crypto in C:\Applications\Apache Software Foundation\Apache2.2\htdocs\magento\lib\Zend\Mail\Protocol\Smtp.php on line 206
Should I be using loadByCode? I wish there was some worthwhile documentation (the help for loadByCode is "Load template by code" !!). Should I be using send, sendTransactional? Oh for a bit of quality documentation.
Thanks
I see 2 questions here.
1. How to configure Magento mailing system to use smtp protocol ?
You are having trouble for this because Magento is made to use default host mailing. So it will search for it on the machine where it is installed.
If you want to configure a smtp server, I would recommend using this extension : http://www.magentocommerce.com/magento-connect/ziq2004/extension/460/advanced-smtp--artson.it
I found it simple to use and configure.
2. How to send a mail in your custom module
You can first create your template in Confguration/Transactional Emails, mark down the Id for it will be your identifier
Then, simply use this code to send the mail in your module
<?php
// The Id you just marked...
$templateId = 1;
// Define the sender, here we query Magento default email (in the configuration)
// For customer support email, use : 'trans_email/ident_support/...'
$sender = Array('name' => Mage::getStoreConfig('trans_email/ident_general/name'),
'email' => Mage::getStoreConfig('trans_email/ident_general/email'));
// Set you store
// This information may be taken from the current logged in user
$store = Mage::app()->getStore();
// In this array, you set the variables you use in your template
$vars = Array('my_var' => $my_var,
'another_var' => 12);
// You don't care about this...
$translate = Mage::getSingleton('core/translate');
// Send your email
Mage::getModel('core/email_template')->sendTransactional($templateId,
$sender,
'recipient#gmail.com',
'Recipient Name',
$vars,
$store->getId());
// You don't care as well
$translate->setTranslateInline(true);
?>
Hope this will help you
Regards,
I took out the 'ssl' => 'tls' element in the array in getMail() in Template.php and my e-mail came through.
I'd still appreciate if anyone has an explanation of how the smtp server's username and password should be specified, and an explanation of the differences in the template load methods etc would be most welcome!
If anyone is looking for full sample code of how to send a Magento email based on an existing Magento email template, the following works well. It does not require any XML config. You can load the template by name as well as by ID. In this case I load it by name.
// This is the name that you gave to the template in System -> Transactional Emails
$emailTemplate = Mage::getModel('core/email_template')->loadByCode('My Custom Email Template');
// These variables can be used in the template file by doing {{ var some_custom_variable }}
$emailTemplateVariables = array(
'some_custom_variable' => 'Hello World'
);
$processedTemplate = $emailTemplate->getProcessedTemplate($emailTemplateVariables);
$emailTemplate->setSenderName('Joe Bloggs');
$emailTemplate->setSenderEmail('test#test.com');
$emailTemplate->setTemplateSubject("Here is your subject");
$emailTemplate->send('recipient#test.com', 'Joanna Bloggs', $emailTemplateVariables);