best way to fix inspection for soapclients in phpstorm - phpstorm

I'm using PHPStorm v3 and have some code which connects to a certain SOAP service. (via a simple PHP SoapClient) No problems whatsoever. But the PHPStorm inspector cant find the methods available of the WSDL and thus cant recognize the used methods:
$this->soap = new SoapClient('somewsdl url');
$issues = $this->soap->getIssuesFromJqlSearch($this->auth,
'ticketId = '.$ticket->getId().'
AND impId ~ "'.$currentImplementation->getIdentifier().'"', 1);
Everything works but the method 'getIssuesFromJqlSearch' which is provided by the external WSDL is highlighted with the mentioning of an undefined method... How can i 'tell' PHPStorm what should/could be used (or explain how to parse the WSDL?)

You can suppress the inspection for this statement from the Alt+Enter, right arrow menu:

This is not perfect, since it does not parse the WSDL and you have to do it manually, but works fine after the initial setup.
Create a class extending the native SoapClient and use annotations to add virtual methods:
/**
* #method mixed getIssuesFromJqlSearch
**/
class VendorSpecific extends \SoapClient {}
Or you could generate such client yourself, implementing all the methods as a proxy to self::__soapCall(). See my SoapClient generator for reference. The upside is that it can parse the WSDL, though not perfectly.

Related

MvvmCross 4 support for UWP, AppShell missing Frame

I have created a new solution for my MvvmCross app that supported Windows Store and I want to support UWP on Windows 10. I have moved over the PCL successfully, but I am having problems getting the basic UWP app working using a sample provided by MS (NavigationMenu) which uses the SplitView and the AppShell pattern they are recommending for the new navigation/command model. I referenced a helpful blog post (http://stephanvs.com/implementing-a-multi-region-presenter-for-windows-10-uwp-and-mvvmcross/), which gave me some guidance on how to integrate mvvmcross into the AppShell, but startup is failing because the AppShell does not have a valid Frame defined. Frame is a read-only property, and I have been unable to see where this is being set up.
I am using the standard AppShell implementation from the NavigationMenu with the following changes as recommended in the blog post:
public sealed partial class AppShell : MvxWindowsPage // was Page
public Frame AppFrame { get { return this.Frame; } } // was this.frame
Except for code after the error, there are no differences in the setup. In looking at the MvxWindowsPage implementation, there doesn't seem to be anything special as it still invokes the Page initialization. Is there something obvious I am missing?
So the link to the blogpost is correct, in other words you'll need to use MultiRegions from MvvmCross to get this working.
But what the blogpost doesn't show is a complete working version...
I've added one on my github here:
https://github.com/Depechie/MvvmCrossUWPSplitView
Some pointers to take away, like I said in the comments.
Your view where the SplitView will be present, needs to have a property to return a valid Frame to look for while injecting new views. This can be returned like this return (Frame)this.WrappedFrame.UnderlyingControl; found in the code here https://github.com/Depechie/MvvmCrossUWPSplitView/blob/master/MvvmCrossUWP.Win/Views/FirstView.xaml.cs#L13
Than all views you want to load up in the SplitView will need to reference to the region you defined in that SplitView, in my case I named it FrameContent as seen here https://github.com/Depechie/MvvmCrossUWPSplitView/blob/master/MvvmCrossUWP.Win/Views/FirstView.xaml#L48
So use that name for the region attribute in all to be loaded views like so [MvxRegion("FrameContent")] example here https://github.com/Depechie/MvvmCrossUWPSplitView/blob/master/MvvmCrossUWP.Win/Views/SecondView.xaml.cs#L7
I see what you're trying to do with the SplitView template that's provided by Microsoft. There is however a mismatch between things managed by MvvmCross and UWP.
By default MvvmCross maps ViewModels to Views based on naming conventions. What you are trying to do is use a view 'AppShell' (which is derived of Windows.UI.Xaml.Controls.Page) that doesn't adhere to the default MvvmCross convention.
The way I choose to implement this SplitView (Hamburger) functionality is by deleting the provided AppShell class entirely. I then created a new view named HomeView (since I have a ViewModel with the name HomeViewModel) and added the SplitView control there as described in the post you mentioned above.
For completeness I've created a Gist with the App.xaml.cs and HomeView.xaml as you requested. You can find them here: https://gist.github.com/Stephanvs/7bb2cdc9dbf15cb7a90f

How to activate IWiFiDirectDevice in Win32 Console APP using WRL?

I want to use WinRT API for WiFi Direct from Windows 10 SDK in Win32 Console Application. I know about C++/CX (and even made some progress going that way), but still want to make it work without this extension.
My problem is that I can't activate IWifiDirectDevice interface (from ABI::Windows::Devices::WiFiDirect) to access IWifiDirectDeviceStatics that provides an GetDeviceSelector method.
HStringReference strDevice(RuntimeClass_Windows_Devices_WiFiDirect_WiFiDirectDevice);
ComPtr<IInspectable> insp;
hr = RoActivateInstance(strDevice.Get(), insp.GetAddressOf());
This code ends up with E_NOTIMPL as a result. In Microsoft's example they used factories for activation, but ABI::Windows::Devices::WiFiDirect namespace has no factories.
Worth mentioning that IWifiDirectAdvertisementPublisher works just fine when activated the way I wrote before.
So how to activate IWifiDirectDevice from WRL?
Windows.Devices.WiFiDirect.WiFiDirectDevice is not an activatable class. You can see that by looking at windows.devices.wifidirect.idl.
You will need to use the static methods, e.g.:
HStringReference strDevice(RuntimeClass_Windows_Devices_WiFiDirect_WiFiDirectDevice);
ComPtr<IWiFiDirectDeviceStatics> wiFiDirectDeviceStatics;
hr = Windows::Foundation::GetActivationFactory(
strDevice.Get(),
&wiFiDirectDeviceStatics);
ComPtr<IWiFiDirectDevice> wiFiDirectDevice;
ComPtr<IAsyncOperation<WiFiDirectDevice*>> asyncOperation;
hr = wiFiDirectDeviceStatics->FromIdAsync(deviceId.Get(), &asyncOperation);
Consider taking a look at the Wi-Fi Direct sample.

How to detect if I am in 'console' mode

I am writing an app that runs from the browser. However, some model functions are also called from the Yii2 console. Therefore, I am getting errors when trying to access variables that are set in the GUI.
Is it possible to tell which mode I am in? Is there some environment variable automatically set, or should I just set some session variable in the console app to indicate the state?
You can use
if (Yii::$app instanceof \yii\console\Application)
for console, and
if (Yii::$app instanceof \yii\web\Application)
for web.
Correct variant
Yii::$app->request->isConsoleRequest
There is a simpler way to figure this out without going through the Yii objects
if (php_sapi_name() == "cli") {
return;
}
...and it works for all PHP scripts
...and it is lighter
By default for console:
Yii::$app->id == 'basic-console'
And for web application:
Yii::$app->id == 'basic'
Yii::$app->id stores the id of the loaded configuration params. By default for console application it is 'basic-console' and for web application it is 'basic' (defined in configuration file)
Yii2 provides a number of different classes for application's console and for those of type web. In addition to this division of the mode of operation of the classes, there are also a set of rules governing the organization of the code of the application. The first, fundamental, it is the respect of giving the MVC Model object information, to view the management interface with the user and, finally, to the controller the role of coordination among them. In your case it seems to sense that a piece of code runs in console but referring to classes that provide a Web interface. Probably because in some Model classes were introduced with functions with HTML or other code that should not be there. If you need two separate applications should precisely separate applications that use a type controls
yii\console\Controller
and another that uses controller type web
yii\web\Controller.
Obviously Model classes will be common and, thanks to separate controller, be sure to invoke View appropriate to the type of user interface in use. I Hope this could be useful.
Works for nginx and apache:
function isConsole()
{
return 'cli' == php_sapi_name() || !array_key_exists('REQUEST_URI', $_SERVER);
}
Pure PHP:
global $argv;
if (empty($argv)) {
// Browser mode
}
else {
// Cli mode
}

Resolving a dependency while supplying values for downstream dependencies

I've been running into endless problems attempting to use Windsor with Web API and injecting HttpRequestMessage into downstream dependencies of a controller. Since I've tried all the matching answers on Stackoverflow, I'd like to ask the question in a different way:
In Castle Windsor, how can I resolve a component instance while supplying a value for a downstream dependency? That is, the supplied value is required by a component that is required by the component being resolved.
For context, I'm trying to inject HttpRequestMessage so that I can use it to resolve the request context (primarily to resolve an absolute URL).
Edit I'd also like to point out that I don't currently have a dependency on Web Host / System.Web and I'd rather not change that.
A proper approach is to
Create IMyDesiredRouteParameterProvider
Implement it. Get the current request inside it and get the url
Register it and inject it in the desired dependent class via constructor.
I made myself such an implementation and I can say that this way it works fine. You can make Web.Infrastructure assembly and put the implementation there. Or put both the interface and the implementation there if you are going to reference it from another web module.
using System;
using System.Web;
namespace RouteParameterProvider
{
interface IMyRouteParameterProvider
{
string GetRouteParameter();
}
public class ControllerActionMethodRouteParameterProvider : IMyRouteParameterProvider
{
public string GetRouteParameter()
{
string Parameter = HttpContext.Current.Request.RequestContext.RouteData.Values["controller"] as string;
if (string.IsNullOrEmpty(Parameter))
{
throw new InvalidOperationException();
}
return Parameter;
}
}
}
You can get every possible thing that the Request Context contains from :
HttpContext.Current.Request.RequestContext
And it will be better if you rethink your design decision :
I need HttpRequestMessage to be regstered prior to creating each
instance of SomethingController so that it will be available down at
the LinkGenerator layer.
Containers are to be initialized at runtime and then used to resolve.
I need HttpRequestMessage to be regstered prior to creating each
instance of SomethingController so that it will be available down at
the LinkGenerator layer.
It sounds like you want to register an item with the container at runtime, post-startup. In general, this is not a good practice--registration should be a discrete event that happens when the app is fired up, and the container's state should not be changed during runtime.
Dependency Injection is about resolving service components, not runtime state--state is generally passed via methods (method injection). In this case it sounds like your LinkGenerator component needs access to the ambient state of the request.
I'm not that familiar with HttpRequestMessage, but this answer seems to show that it is possible to retreive it from HttpContext.Current. You could make this a method on your LinkGenerator class, or wrap this call in a separate component that gets injected into LinkGenerator (HttpRequestMessageProvider?). The latter would be my preferred method, as it allows LinkGenerator to be more testable.
Given the lack of a clean way of doing this and Web API not providing information as to the hosted endpoint beyond per-request context objects, I ended up injecting the base url from configuration.
Is this library by Mark Seemann the answer? In the description he writes explicitly :
This approach enables the use of Dependency Injection (DI) because the
request can be injected into the services which require it.
Then gives an example :
// Inside an ApiController
var uri = this.Url.GetLink(a=> a.GetById(1337));
By which you can then pass the URL down the road in the service that you have injected in the controller.
UPDATE :
Mark Seemann wrote about the same exact problem here:
"Because HttpRequestMessage provides the context you may need to
compose dependency graphs, the best extensibility point is the
extensibility point which provides an HttpRequestMessage every time a
graph should be composed. This extensibility point is the
IHttpControllerActivator interface:..."
This way you can pass request context information to a component deep in the object graph by getting from the HttpRequestMessage and passing it to the DI container.
Just take a look at the interface of IHttpControllerActivator.
The WEB API framework gets the IHttpControllerActivator through DependencyResolver. You probably already replaced it by your CastleWindsorDependencyResolver. Now you have to implement and register your HttpControllerActivator and register it.
When the WEB API framework gets IHttpControllerActivator from DependencyResolver (your Castle Windsor DR) and calls IHttpControllerActivator.Create() it will pass you the HttpRequestMessage. You can get your info from there and pass it to the your CastleDR before you call Resolve(typeof(MyController)) which will resolve the whole object graph - that means you will have MyHttpContextInfo to inject in your XYZComponent deep in the resolution stack.
This way tou are passing the arguments in the last possible moment but it is still possible. In Castle Windsor I make such passing of arguments though CreationContext.AdditionalArguments["myArgument"];.

Angular - building a "public" function (newbie)

I'm After several days learning angularJS through converting my standart JS app to a ng one.
I was wondering about this simple scenario:
I have a global function called fb_connect(),
it can be used from any page (or any controller if you like) to make a facebook-based login.
This function makes a simple http call and receives a JSON object contain data to move on (display a pop up, login, etc...)
I read that I can define a Factory or a Service for my app and use it in any controller, which works fine.
So, I created a fb_connect factory function.
The problem is that now, in every page (every controller), I have to define that fb_connect in the constructor of every controller - for example :
function welcome($scope,fb_connect){});
What is the proper way to do this kind of actions using Angular without having to define these functions each and every time in every controller?
Thanks
Setting up factories and services is all part of the dependency injection system of Angular. Using that system is great when you need to create things that depend on other injected things. It's a big tree of dependencies. It's also nice for creating singletons, such that everywhere in your code end up using the same instance of some object.
It sounds to me like neither of these benefits apply in your case. I'd suggest just not using Angular's DI for it. You have some function defined globally, just call it directly and skip the DI. There's nothing wrong with that.
Of course you say it makes an Ajax call, so doesn't depend on the Angular $http service?
Your two options are:
Declare the function on the $rootScope
Inject it as a service
My advice is to go with making it a service. The whole purpose of services is explained in the Angular.js docs, just like this quote:
Angular services are singletons that carry out specific tasks common to web apps... To use an Angular service, you identify it as a dependency for the dependent (a controller, or another service) that depends on the service.
As you mentioned in your question, you'd prefer to not define the service in every controller you wish to use it in. With $rootScope you'll be injecting that also in every controller. So really it's a question of which you prefer, although to answer your question, the proper way of using a factory or service is to inject it into the controller you wish to use it in.
You can always put it in the $rootScope
myApp.run(function($rootScope, fb_connect){
$rootScope.welcome = function(){
};
});