using zend_soap_autoDiscover in codeIgniter - php

I install zend_framework on my CodeIgniter and load the "Zend/Soap/AutoDiscover".
Now I want to add function to autoDiscover and generated WSDL for it. this is what have I done:
class Api extends CI_Controller {
public function update_profile() {
$this->load->library('zend');
$this->zend->load('Zend/Soap/AutoDiscover');
$autodiscover = new Zend_Soap_AutoDiscover();
$autodiscover->addFunction( 'hello' );
$autodiscover->handle();
}
public function hello() {
return "Hello world";
}
}
What should I do to solve this error?

This is because the Zend_Soap_AutoDiscover expects simple global functions and not method names in the addFunction method. If you poke around the stacktrace you will se that the parameter you add will be checked against this down the line (just before throwing exception):
if (!is_string($function) || !function_exists($function)) {
// exception is thrown here
}
What you could use instead is the setClass method. With this you can expose every public method of a class. For this you might find it more feasible to define a different class other then a constructor that does the real work and if you have a controller then just delegate to the service class from there.

Related

Nusoap accessing $this inside method - using $this when not in object context

I have a nusoap class, with some methods defined in the constructor. The problem I'm having however, is calling a method either from a model I loaded or a method defined in the same class out of the constructor. The error I get is "Using $this when not in object context". None of the methods are static, so I'm not sure why it's having trouble accessing this. For reference, here is an example of what I'm trying to do.
edit: This is my first time working with nusoap, and the methods were defined in the constructor in all the examples I saw. If the methods do not need to be defined in the constructor, where do I define them?
class MySoapServer extends CI_Controller {
function __construct() {
parent::__construct();
//where I'm loading all my models and libraries,
//creating a new instance of soap server
//and registering all my methods
function myFunction() {
$this->testFunction() //this is where it errors out
}
}
function testFunction() {
return true;
}
}
Your function is in another function, it should look like:
class MySoapServer extends CI_Controller {
function __construct() {
parent::__construct();
//where I'm loading all my models and libraries,
//creating a new instance of soap server
//and registering all my methods
}
function myFunction() {
$this->testFunction() //this is where it errors out
}
function testFunction() {
return true;
}
}
What you seem to be trying to do is run testFunction() in the constructor? If that's the case then myFunction() isn't needed and you just need to add $this->testFunction() at the end of the constructor.
Like this:
class MySoapServer extends CI_Controller {
function __construct() {
parent::__construct();
//where I'm loading all my models and libraries,
//creating a new instance of soap server
//and registering all my methods
$this->testFunction();
}
function testFunction() {
return true;
}
}
I'm Not an expert on nusoap but PHP does not handle nested function very well. Why would you declare "myFunction" inside of the constructor? Try removing the nested function out of the constructor. Also, you might want to try and set the access modifiers of the function.

Execute repository functions in scheduler task

Currently I have an scheduler task, but I want to use function from my extbase repository (in the same extension).
I keep getting "PHP Fatal error: Call to a member function add() on a non-object", no matter how I try to include my repo or controller from extbase.
My SampleTask.php:
namespace TYPO3\ExtName\Task;
class SampleTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask {
public function execute() {
$controller = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('\TYPO3\ExtName\Controller\SampleController');
$new = new \TYPO3\ExtName\Domain\Model\Sample;
$new->setName('test');
$controller->createAction($new);
}
}
And correctly defined in my ext_localconf.php
Can someone explain me how I can access my Repository (or controller) -extbase- from my SampleTask.php.
Using TYPO3 6.2.
Thank you.
You are getting this php error, because you instanciated your controller with makeInstance(). If you use makeInstance to get the objectManager (\TYPO3\CMS\Extbase\Object\ObjectManager) and use $objectManager->get('TYPO3\ExtName\Controller\SampleController'), the dependency injection inside your controller will work (e.g. your repository).
But you can use the objectManager to get the repository right away, so you dont have to call a controller action:
Something like this:
namespace TYPO3\ExtName\Task;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\ExtName\Domain\Repository\SampleRepository;
use TYPO3\ExtName\Domain\Model\Sample;
use TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface;
class SampleTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask {
public function execute() {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$sampleRepository= $objectManager->get(SampleRepository::class);
$new = new Sample();
$new->setName('test');
$sampleRepository->add($new);
$objectManager->get(PersistenceManagerInterface::class)->persistAll();
}
}

Implementing ServiceLocatorAwareInterface dependency for forward() class in a ZF2 service

EDITED (Code is updated and working for others)
For the overall idea of what's happening.
I'm trying to access post data from the view in the controller, without refreshing the page.
To do this I am executing the page controller by using a ViewHelper to call the Service below which then forwards back to the controller; afterwards I can manage the posted data in the page controller.
Everything works except the last step which is the forward(), I receive the error Call to undefined method AlbumModule\Service\postAlbumService::forward()
I understand I must implement the ServiceLocatorAwareInterface in order to use the forward() class, but what I've written doesn't seem to work.
<?php
namespace AlbumModule\Service;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class postAlbumService implements
ServiceLocatorAwareInterface
{
protected $services;
public function __construct() {
echo '<script>console.log("postAlbumService is Started")</script>';
}
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->services = $serviceLocator;
}
public function getServiceLocator()
{
return $this->services;
}
public function test(){
$cpm = $this->getServiceLocator()->get('controllerpluginmanager');
$fwd = $cpm->get('forward');
echo '<script>console.log("postAlbumService TEST() is Started")</script>';
return $fwd->dispatch('newAlbum', array('action' => 'submitAlbum'));
}
}
It seems as though I'm just having a dependency issue with the forward() class, but I'm not sure what the issue is.
EDIT-
Here is how I am calling the postAlbumService from the viewHelper
<?php
namespace AlbumModule\View\Helper;
use Zend\View\Helper\AbstractHelper;
class invokeIndexAction extends AbstractHelper
{
protected $sm;
public function test()
{
$this->sm->getServiceLocator()->get('AlbumModule\Service\postAlbumService')->test();
}
public function __construct($sm) {
$this->sm = $sm;
}
}
Is there any way to call a specific class in the service being requested, after the dependencies are injected into the service?
You're doing a couple of things wrong and you're misunderstanding some things...
First of all, forward() is a ControllerPlugin. You'll gain access to this method by accessing said manager via the ServiceLocator. An example could be this:
$cpm = $serviceLocator->get('controllerpluginmanager');
$fwd = $cpm->get('forward');
return $fwd->dispatch('foo/bar');
Now, to get the ServiceLocator into any of your Service-Classes you need Dependency Injection. One of the ways is to implement the ServiceLocatorAwareInterface. The ServiceManager of ZF2 has so called Listeners. These Listeners check for implemented interfaces and stuff like this. Whenever it finds a match, it injects the required dependencies via the interfaces given functions. The workflow looks like this:
ServiceManager get('FooBar');
$ret = new FooBar();
foreach (Listener)
if $ret instanceof Listener
doInjectDependenciesInto($ret)
end
end
return $ret
Now what does this tell you. This tells you, that within the __construct() of any of your classes NONE of your required dependencies are actually there. They only get injected AFTER the class/service has been instantiated.
On a last side-note, the given code example doesn't really make much sense ;) No matter what ServiceAction i'd like to access, you'd always return me to the "newAlbum" action...

Why can't CodeIgniter autoload my Exceptions file in application/core?

I have an exception in application/core named prefix_Exceptions.php with the same class name. I try to throw this exception from a controller and I get:
Fatal error: Class 'prefix_Exceptions' not found in user_controller.php
In application/core/prefix_Exceptions.php:
<?php
class prefix_Exceptions extends CI_Exceptions {
public function __construct() {
parent::__construct();
}
public function test() {
echo "This is a test.";
}
}
And in application/controllers/user_controller.php:
<?php
class User_Controller extends CI_Controller {
public function view($id = '0') {
$this->load->model('user_model');
$u = $this->user_model->getUser($id);
if (!isset($u)) {
$this->exceptions->test(); // ???
}
echo "Test: $u";
}
}
Oh, and my prefix is set to prefix_:
$config['subclass_prefix'] = 'prefix_';
I've read about a dozen threads on this issue and none of them fix my exception so that it can be thrown by the controller.
The main reason your code is not working, is (as the error message suggests): your prefix_invalid_user.php is never loaded. CI does not know to load this file, as you are not following the required file naming scheme.
If you want to extend a built-in class, you have to use the same class name, except you change the prefix from CI_ to MY_ (or whatever prefix you set in your config).
To extend the class CI_Exceptions you would have to name it MY_Exceptions and save that php file in /application/core/MY_Exceptions.php. Then, and only then, will CI auto-load it for you.
However you should also know that CI's exceptions class isn't actually for throwing exceptions (the name is misleading, but CI_Exceptions handles error reporting). As you can see in the /system/core/Exceptions.php file, the CI_Exceptions class does not extend PHP's native Exceptions class, which is necessary to create custom, throwable exceptions.
If you want custom, throwable exceptions you have to create your own wrapper for them, and load/autoload it as a library.
Edit:
As per the OP's request, I'm adding the other half of the solution, which was to simply fetch the class object from CI's innards. For this, we can use the load_class function, which will return our class object if it has been instantiated, and if not, it will instantiate and return it.
$foo = load_class('Exceptions', 'core', $this->config->item('subclass_prefix'))
Then we can access the methods of our custom Exceptions class as so:
$foo->someMethodName();

Illuminate components in packages

I have a self-made package. With the service provider I pass the $app instance to the actual class. Then I use:
$this->app['session']->get('key', 'value');
to use the Session component's functionality. However, when I run this, I get the following error:
Using $this when not in object context
So I tried just using
Session::get( ... )
but then it says it doesn't find the class.
How do I solve this?
This is my full class:
namespace AlexCogn\Messenger;
use Illuminate\Foundation\Application as Application;
class Messenger
{
protected $app;
public function __construct(Application $app)
{
$this->app = $app;
}
public static function messages()
{
$messages = $this->app['session']->get('messages', array());
$this->app['session']->forget('messages');
return $messages;
}
public function addMessage($message)
{
$messages = $this->app['session']->get('messages', array());
array_push($messages, $message);
$this->app['session']->put('messages', $messages);
}
}
EDIT:
apparently not everyone understands the question: I am calling Messenger through a Facade:
Messenger::addMessage('test');
and I thought Laravel converted this to
$app['messenger']->addMessage('test');
So shouldn't this be called via an instance?
You are trying to call $this from a static method within your class. This won't work. By PHP definition (and also because it'd be stupid otherwise), $this is only available in the following scopes:
Inside a method that has been called through an instance (i.e. $this->foo())
Inside a class constructor (inside __construct())
Inside a Callable where this has been redefined using the Runkit library
Anything else causes this to trigger the fatal error you have just received. I cannot suggest a fix, as you did not put your code up - however, if you do, I'll be more than happy to find a solution for you.

Categories