Sending a SOAP message with PHP - soap

what I'm trying to do is send a load of values captured from a form to a CRM system with SOAP and PHP. I've been reading up on SOAP for a while and I don't understand how to go about doing so, does anybody else know?

In order to do this it might be easiest to download a simple soap toolkit like 'NuSOAP' from sourceforge.
And then you would code something like the following (example submission of ISBN number):
<?php
// include the SOAP classes
require_once('nusoap.php');
// define parameter array (ISBN number)
$param = array('isbn'=>'0385503954');
// define path to server application
$serverpath ='http://services.xmethods.net:80/soap/servlet/rpcrouter';
//define method namespace
$namespace="urn:xmethods-BNPriceCheck";
// create client object
$client = new soapclient($serverpath);
// make the call
$price = $client->call('getPrice',$param,$namespace);
// if a fault occurred, output error info
if (isset($fault)) {
print "Error: ". $fault;
}
else if ($price == -1) {
print "The book is not in the database.";
} else {
// otherwise output the result
print "The price of book number ". $param[isbn] ." is $". $price;
}
// kill object
unset($client);
?>
This code snippet was taken directly from, which is also a good resource to view
http://developer.apple.com/internet/webservices/soapphp.html
Hope this helps.

You probably found a solution since then - but maybe the following helps someone else browsing for this:
soap-server.php:
<?php
class MySoapServer {
public function getMessage ()
{
return "Hello world!";
}
public function add ($n1,$n2)
{
return $n1+n2;
}
}
$option = array ('uri' => 'http://example.org/stacky/soap-server');
$server = new SoapServer(null,$option);
$server->setClass('MySoapServer');
$server->handle();
?>
and soap-client.php
<?php
$options = array ('uri' => 'http://example.org/stacky/soap-server',
'location' => 'http://localhost/soap-server.php');
$client = new SoapClient(null,$options);
echo $client ->getMessage();
echo "<br>";
echo $client ->add(41,1);
?>

Related

Joomla module not working

I made a module that display how many days ago a article was published
it looks like this.
{source}
<?php
$jinput = JFactory::getDocument()->input;
$option = $jinput->get('option');
$view = $jinput->get('view');
if ($option=="com_content" && $view=="article") {
$ids = explode(':',JRequest::getString('id'));
$article_id = $ids[0];
$article =& $jinput->get("content");
$article->load($article_id);
$date = new JDate($article->get("publish_up"));
$currentTime = new JDate('now');
$interval = $date->diff($currentTime);
if($interval->d == 0) {
echo 'dzisiaj' . "<br>";
}
else if( $interval->d == 1) {
echo 'wczoraj' . "<br>";
}
else if( $interval->d > 1) {
echo $interval->format('%a dni temu') . "<br>";
}
}
?>
{/source}
And it works on my local joomla but when use it on custom template it doesnt work. I'm using Joomla 3.4.8.
The issue is you're trying to access the input values using Document Factory that's wrong you have to use
$jinput = JFactory::getApplication()->input;
Document Factory is used for other purpose like adding , styles or Js to the pages etc. read more about input here.
Hope it make sense.

ZF2 - Show just one error on forms

I can't seem to get ZF2 to show just one error message for failed form validation messages.
For example, an EmailAddress validator can pass back up to 7 messages and typically shows the following if the user has made a typo:
oli.meffff' is not a valid hostname for the email address
The input appears to be a DNS hostname but cannot match TLD against known list
The input appears to be a local network name but local network names are not allowed
How can I override the error to show something a little more friendly, such as "Please enter a valid email address" instead of specifics like the above?
OK, managed to come up with a solution for this. Instead of using the same string as the error for all validator failures as Sam suggested above, I have overridden the error messages in the InputFilter for the elements and then used a custom form error view helper to show only the first message.
Here is the helper:
<?php
namespace Application\Form\View\Helper;
use Traversable;
use \Zend\Form\ElementInterface;
use \Zend\Form\Exception;
class FormElementSingleErrors extends \Zend\Form\View\Helper\FormElementErrors
{
/**
* Render validation errors for the provided $element
*
* #param ElementInterface $element
* #param array $attributes
* #throws Exception\DomainException
* #return string
*/
public function render(ElementInterface $element, array $attributes = array())
{
$messages = $element->getMessages();
if (empty($messages)) {
return '';
}
if (!is_array($messages) && !$messages instanceof Traversable) {
throw new Exception\DomainException(sprintf(
'%s expects that $element->getMessages() will return an array or Traversable; received "%s"',
__METHOD__,
(is_object($messages) ? get_class($messages) : gettype($messages))
));
}
// We only want a single message
$messages = array(current($messages));
// Prepare attributes for opening tag
$attributes = array_merge($this->attributes, $attributes);
$attributes = $this->createAttributesString($attributes);
if (!empty($attributes)) {
$attributes = ' ' . $attributes;
}
// Flatten message array
$escapeHtml = $this->getEscapeHtmlHelper();
$messagesToPrint = array();
array_walk_recursive($messages, function ($item) use (&$messagesToPrint, $escapeHtml) {
$messagesToPrint[] = $escapeHtml($item);
});
if (empty($messagesToPrint)) {
return '';
}
// Generate markup
$markup = sprintf($this->getMessageOpenFormat(), $attributes);
$markup .= implode($this->getMessageSeparatorString(), $messagesToPrint);
$markup .= $this->getMessageCloseString();
return $markup;
}
}
It's just an extension of FormElementErrors with the render function overridden to include this:
// We only want a single message
$messages = array(current($messages));
I then insert the helper into my application using the solution I posted to my issue here.

Access Form values in my Symfony executeAction backend

So one of my pages consists of a quiz form that has several questions of type multiple choice, the choices are specified as radio buttons. I have been scanning the Symfony documentation to find out how to access form field values inputted by the user. Thing is, this isn;t a doctrine or propel based form, and neither do I require the values to be stored in the database, hence executing a $form->save() makes little sense to me. But I do require access to specific values of my form in my backend once the user hits submit.
Most of Symfony documentation that i have run into doesn't necessarily explain how this can be done. I would assume it would be something to the effect of :
$request->getParameter( 'radio_choices_id selected value ').
Thanks to all who read this and Cheers to the ones who respond to it :)
Parijat
Hm, it is very simple if I understand your question right)
For widget:
$this->widgetSchema['name'] = new sfWidgetFormChoice(array('choices' => array('ch_1', 'ch_2')));
Ok,in action:
$this->form = new FaqContactForm();
if ($request->isMethod('post')) {
$this->form->bind($request->getParameter($this->form->getName()));
if ($this->form->isValid()) {
$your_val=$this->form->getValue('name');
//or
$your_val=$this->form['name']->getValue());
}
}
In backend in protected function processForm(sfWebRequest $request, sfForm $form)
you have
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
$notice = $form->getObject()->isNew() ? 'The item was created successfully.' : 'The item was updated successfully.';
try {
$product = $form->save();
} catch (Doctrine_Validator_Exception $e) {
$errorStack = $form->getObject()->getErrorStack();
$message = get_class($form->getObject()) . ' has ' . count($errorStack) . " field" . (count($errorStack) > 1 ? 's' : null) . " with validation errors: ";
foreach ($errorStack as $field => $errors) {
$message .= "$field (" . implode(", ", $errors) . "), ";
}
$message = trim($message, ', ');
$this->getUser()->setFlash('error', $message);
return sfView::SUCCESS;
}
Before $product = $form->save(); try
$your_val=$form->getValue('name');
//or
$your_val=$form['name']->getValue());

unset session variable in zend view

I ll reframe my question based on some research I have done?
I need to store lot of errors separately like $_SESSION['client_error'],$_SESSION['state_error'] etc.
According to zend documentation do I have to store it like this for each error?
$client_error = new Zend_Session_Namespace(''client_error);
$state_error = new Zend_Session_Namespace('state_erro'); and so on?
This is my code in the controller.
I am storing it as
$this->view->state_error_message=$state_error;
After I echo $this->state_error in the view I want to unset it.
Ok here are few more things I tried:
In the controller in policyInfoAction:
session_start();
$error_message = new Zend_Session_Namespace('error_message');
$error_message="TEST";
$this->view->error_message=$error_message;
$this->_redirect('/pdp/client-info/');
In the view in client-info:
session_start();
<?php echo $this->error_message; ?>
This returns nothing.
Ok this is my updated code:
public function clientInfoAction()
{
$errors = new Zend_Session_Namespace('errors');
// get the error arrays
$client_errors = (isset($errors->client_error)) ? $errors->client_error : array();
$state_errors = (isset($errors->state_error)) ? $errors->state_error : array();
unset($errors->client_error, $errors->state_error); // delete from the session
// assign the values to the view
$this->view->client_errors = $client_errors;
$this->view->state_errors = $state_errors;
}
public function policyInfoAction()
{
if (count($arrErrors) > 0)
{
// The error array had something in it. There was an error.
$strError="";
foreach ($arrErrors as $error)
{
$strError="";
$errors->client_error = array();
$errors->state_error = array();
foreach ($arrErrors as $error)
{
$strError .= $error;
// to add errors to each type:
$errors->client_error['client_error'] = $strError;
$errors->client_error[] = $strError;
$this->_redirect('/pdp/client-info/');
}
}
}
When i echo $this->client_errors I get 'Array'
Here is some advice and suggestions that can hopefully get you on the right track.
First, when using Zend_Session and/or Zend_Session_Namespace, you never want to use PHP's session_start() function1. If you start a session with session_start(), and then try to use Zend_Session, it will throw an exception that another session already exists.
Therefore, remove all session_start() calls from your Zend Framework application.
Second, you mentioned you had a lot of messages you need to store, so this may not be the right thing for you, but see the FlashMessenger action helper. This allows you to set a message in a controller, and then access it on the next page request. The messages only live for one page hop, so after the next page load, they are deleted. You can store many messages with the FlashMessenger, but your access to them is not very controlled. You could use multiple flash messengers each in differen namespaces also.
To solve your problem in particular, you could just do something like this:
// in controller that is validating
$errors = new Zend_Session_Namespace('errors');
$errors->client_error = array();
$errors->state_error = array();
// to add errors to each type:
$errors->client_error['some_error'] = 'You had some error, please try again.';
$errors->client_error['other_error'] = 'Other error occurred.';
$errors->client_error[] = 'Other error, not using a named key';
$errors->state_error[] = MY_STATE_PARSING_0;
What is happening here is we are getting a session namespace called errors creating new properties for client_error and state_error that are both arrays. You don't technically have to use multiple Zend_Session_Namespaces.
Then to clear the messages on the next page load, you can do this:
// from controller again, on the next page load
$errors = new Zend_Session_Namespace('errors');
// get the error arrays
$client_errors = (isset($errors->client_error)) ? $errors->client_error : array();
$state_errors = (isset($errors->state_error)) ? $errors->state_error : array();
unset($errors->client_error, $errors->state_error); // delete from the session
// assign the values to the view
$this->view->client_errors = $client_errors;
$this->view->state_errors = $state_errors;
See also the source code for Zend_Controller_Action_Helper_FlashMessenger which can give you some idea on managing data in session namespaces.
I don't know if this will help you or not but here is the code for a controller that just takes an id from a form a gathers data based on that id an assigns that data to the session (to be used throughout the module) and then unsets that data when appropriate. and Never leaves the Index page.
<?php
class Admin_IndexController extends Zend_Controller_Action
{
//zend_session_namespace('location')
protected $_session;
/**
*set the layout from default to admin for this controller
*/
public function preDispatch() {
$this->_helper->layout->setLayout('admin');
}
/**
*initiaize the flashmessenger and assign the _session property
*/
public function init() {
if ($this->_helper->FlashMessenger->hasMessages()) {
$this->view->messages = $this->_helper->FlashMessenger->getMessages();
}
//set the session namespace to property for easier access
$this->_session = new Zend_Session_Namespace('location');
}
/**
*Set the Station and gather data to be set in the session namespace for use
* in the rest of the module
*/
public function indexAction() {
//get form and pass to view
$form = new Admin_Form_Station();
$form->setAction('/admin/index');
$form->setName('setStation');
$this->view->station = $this->_session->stationName;
$this->view->stationComment = $this->_session->stationComment;
$this->view->form = $form;
try {
//get form values from request object
if ($this->getRequest()->isPost()) {
if ($form->isValid($this->getRequest()->getPost())) {
$data = (object)$form->getValues();
//set session variable 'station'
$this->_session->station = $data->station;
$station = new Application_Model_DbTable_Station();
$currentStation = $station->getStation($this->_session->station);
$this->_session->stationName = $currentStation->station;
$this->_session->stationComment = $currentStation->comment;
//assign array() of stations to session namespace
$stations = $station->fetchAllStation();
$this->_session->stations = $stations;
//assign array() of bidlocations to session namespace
$bidLocation = new Application_Model_DbTable_BidLocation();
$bidLocations = $bidLocation->fetchAllBidLocation($this->_stationId);
$this->_session->bidLocations = $bidLocations;
$this->_redirect($this->getRequest()->getRequestUri());
}
}
} catch (Zend_Exception $e) {
$this->_helper->flashMessenger->addMessage($e->getMessage());
$this->_redirect($this->getRequest()->getRequestUri());
}
}
/**
*Unset Session values and redirect to the index action
*/
public function changestationAction() {
Zend_Session::namespaceGet('location');
Zend_Session::namespaceUnset('location');
$this->getHelper('Redirector')->gotoSimple('index');
}
}
just to be complete i start the session in the bootstrap. On the theory that if I need it great if not no harm.
protected function _initsession() {
//start session
Zend_Session::start();
}
this is all the view is:
<?php if (!$this->station): ?>
<div class="span-5 prepend-2">
<?php echo $this->form ?>
</div>
<div class="span-10 prepend-2 last">
<p style="font-size: 2em">Please select the Station you wish to perform Administration actions on.</p>
</div>
<?php else: ?>
<div class="span-19 last">
<?php echo $this->render('_station.phtml') ?>
</div>
<?php endif; ?>

CodeIgniter: Cannot redirect after $this->email->send()

i have the following code which sends an email from a posted form:
$this->load->library('email');
$config['charset'] = 'iso-8859-1';
$config['mailtype'] = 'html';
$this->email->initialize($config);
$this->email->from('info#mysite.com', 'Scarabee');
$this->email->to('info#mysite.com');
$this->email->subject('Message via website');
$data['msg'] = nl2br($this->input->post('msg'));
$data['msg'] .= '<br><br><b>Verstuurd door:</b><br>';
if($this->input->post('bedrijf')){
$data['msg'] .= $this->input->post('bedrijf').'<br>';
}
$data['msg'] .= $this->input->post('naam').'<br>';
$data['msg'] .= $this->input->post('adres').' - '.$this->input->post('postcode').', '.$this->input->post('gemeente').'<br>';
$data['msg'] .= $this->input->post('tel').'<br>';
$data['msg'] .= $this->input->post('email');
$message = $this->load->view('email', $data, TRUE);
$this->email->message($message);
if($this->email->send()){
$success = 'Message has been sent';
$this->session->set_flashdata('msg', $success);
redirect('contact/'.$this->input->post('lang'));
}
else{
show_error('Email could not be sent.');
}
Problem: the email gets sent with proper formatting (from the email view template), but the page then goes blank. For instance, if I try to echo out $message just below the $this->email->send() call, nothing shows up. Redirecting, as I’m attempting above, obviously doesn’t work either. Am I missing something? Thanks for any help…
Update
Traced the problem down to a function inside /system/libraries/Email.php (CI's default email library). Commenting out the code inside this function allows the mail to get sent, as well as a proper redirect:
protected function _set_error_message($msg, $val = '')
{
$CI =& get_instance();
$CI->lang->load('email');
if (substr($msg, 0, 5) != 'lang:' || FALSE === ($line = $CI->lang->line(substr($msg, 5))))
{
$this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
}
else
{
$this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
}
}
The line that caused the error is: $CI->lang->load('email');
Go figure...
UPDATE 2: SOLVED
I had this in my controller's construct:
function __construct() {
parent::__construct();
$this->lang = $this->uri->segment(2, 'nl');
}
I guess there was a conflict between $this->lang and the _set_error_message function which also returns a "lang" variable (see var_dump further down).
Solution: changed $this->lang to $this->language, and everything's hunky dory!
Thought I'd post the answer here in case anyone else is ever losing hair with a similar problem :-)
It's likely that an error is occurring when you attempt to send an e-mail which is then killing your script during execution. Check your apache and PHP error logs ( /var/log/apache/ ) and enable full error reporting.
You could, for debugging purposes, try doing this:
...
$this->email->message($message);
$this->email->send();
redirect('contact/'.$this->input->post('lang'));
This should redirect you, regardless of your mail being sent or not (if you still recieve it, you can assume that the redirect would be the next thing that happens).
My own solution looks like this:
...
if ( $this->email->send() )
{
log_message('debug', 'mail library sent mail');
redirect('contact/thankyou');
exit;
}
log_message('error', 'mail library failed to send');
show_error('E-mail could not be send');
$ref2 = $this->input->server('HTTP_REFERER', TRUE);
redirect($ref);
By using the above code you can redirect to the current page itself
and you can set your flash message above the redirect function.