I need to create a model admin class to be able to create pages in model admin style. It used to work on 2.4 but not since LeftAndMain::ForceReload has been deprecated in 3.1 it doesn't work anymore. Here is a fragment of my CustomCalendarEvent class:
public function onBeforeWrite(){
parent::onBeforeWrite();
$parent_calendar_page = Calendar::get()->first();
$this->ParentID = $parent_calendar_page->ID;
}
public function onAfterWrite(){
parent::onAfterWrite();
if(!$this->isPublished()){
$this->publish('Stage', 'Live');
$this->flushCache();
// This doesn't work anymore on SS 3.1
// LeftAndMain::ForceReload();
}
}
Related
I'm using SugarCRM to develop a software for customers management. I created a custom module from basic template with custom fields. Is it possible to get rid of SugarCRM db and perform CRUD operations through external web serivices? Actually I was able to show web services data in the datailview by setting the bean property of a custom controller.
class CustomerController extends SugarController{
public function action_detailview(){
$customer = new Customer();
$customer = getCustomerFromWebService();
$this->bean = $customer;
$this->view = "detail";
}
}
I would like to do the same thing with listview, but I don't know how set the records of the list (if it exists) used by the default listview.
You can change list view by customizing view.list.php in custom/modules/modulename/views/view.list.php using following code:
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
require_once('include/MVC/View/views/view.list.php');
// name of class match module
class modulenameViewList extends ViewList{
// where clause that will be inserted in sql query
var $where = 'like 'htc'';
function modulenameViewList()
{
parent::ViewList();
}
/*
* Override listViewProcess with addition to where clause to exclude project templates
*/
function listViewProcess()
{
$this->lv->setup($this->seed, 'include/ListView/ListViewGeneric.tpl', $this->where, $this->params);
echo $this->lv->display();
}
}
?>
I need to use a REST service in order to get some data to a plugin. In order to do so, I have overriden the normal backend interface in typoscript with the following command :
objects.Tx_Extbase_Persistence_Storage_BackendInterface.className = Tx_extensionname_Persistence_Storage_RestBackend
This BackendInterface then returns Query Objects in my repository when I use to following:
Ex:
$query = $this->createQuery();
$query = $query->execute()->toArray();
Here, $query holds the response from the service as a TYPO3 Tx_Extbase_Persistence_QueryInterface object.
The problem is that I need to be able to do a call to the service while passing an ID parameter (appending to the endpoint with /ID). Ideally, I would do it in such a way that this repo function (called in the controller) would return what I want :
public function findById( $id ) {
$query = $this->createQuery();
$query->matching($query->equals('id', $id));
return $query->execute()->toArray();
}
The problem is that I need to be able to access the query constraint within my Tx_extensionname_Persistence_Storage_RestBackend. Normally, I would use the '$query->getConstraint()' method. However, we are using typo3 4.5 and this function is not yet defined for Tx_Extbase_Persistence_QueryInterface.
Modifying the typo3 core to add this function is not an option.
I tried to extend the Query Interface to add this functionnality in a subclass in order to then override the class in typoscript but then realized this wouldn't be portable enough. I need to be able to access the query constraint only using typo3 4.5 native functionnalities.
Well I fixed it. The only thing needed to do was :
Tx_Extbase_Persistence_QueryInterface.className = Tx_MyExtension_Persistence_RestQuery
class Tx_MyExtension_Persistence_RestQuery extends Tx_Extbase_Persistence_Query implements Tx_MyExtension_Persistence_RestQueryInterface
{
}
interface Tx_MyExtension_Persistence_RestQueryInterface extends Tx_Extbase_Persistence_QueryInterface {
public function getConstraint();
}
I'm attempting to create a user login for Facebook and Windows LiveId using DotNetOpenAuth 4.1.0.12182
However the examples in the download make use of DotNetOpenAuth.ApplicationBlock and DotNetOpenAuth.ApplicationBlock.Facebook which don't exist in the current build.
Instead there is the DotNetOpenAuth.AspNet.Clients namespace which includes FacebookClient and WindowsLiveClient - however I can't find any example of how to use these.
Do any examples or documentation exist?
I have been able to get DNOA version 4.1.0.12182, .Net 3.5 and Facebook to work with each other by creating a FacebookAuthClient that is derived off of the DotNetOpenAuth.OAuth2.WebServerClient. One little gotcha that I have found is that if you are using cookie based sessions then you have to access the session before you use the OAuth functionality. From what I can tell this is because DNOA uses the Session ID as the state parameter and if session has never been accessed it can change between requests. This will cause a state parameter mismatch error when the response comes back from Facebook.
FacebookAuthClient:
public class FacebookAuthClient : DotNetOpenAuth.OAuth2.WebServerClient
{
private static readonly DotNetOpenAuth.OAuth2.AuthorizationServerDescription Description = new DotNetOpenAuth.OAuth2.AuthorizationServerDescription
{
TokenEndpoint = new Uri("https://graph.facebook.com/oauth/access_token"),
AuthorzationEndpoint = new Uri("https://graph.facebook.com/oauth/authorize")
};
public static readonly string [] ScopeNeeded = { "publish_stream" };
public FacebookAuthClient()
: base(Description)
{
}
}
Facebook.aspx.cs:
public partial class FacebookPage : System.Web.UI.Page
{
private FacebookAuthClient _client = new FacebookAuthClient
{
ClientIdentifier = ConfigurationManager.AppSettings["FBClientId"], //The FB app's Id
ClientCredentialApplicator = DotNetOpenAuth.OAuth2.ClientCredentialApplicator.PostParameter(ConfigurationManager.AppSettings["FBClientSecret"]) // The FB app's secret
}
protected void Page_Load(object sender, EventArgs e)
{
DotNetOpenAuth.OAuth2.IAuthorizationState auth = _client.ProcessUserAuthorization();
if (_auth == null)
{
// Kick off authorization request with the required scope info
client.RequestUserAuthorization(FacebookAuthClient.ScopeNeeded);
}
}
}
This is just a test app so there is no error handling but it seems to work.
Edit
I used the DotNetOpenAuth(unified) NuGet package for all of this.
Edit
Added missing .PostParameter call to the creating of the ClientCredentialApplicator.
You'll need to use ctp version 3.5 of DNOA. Version 4+ has been made to work with a later draft of OAuth 2 then Facebook uses.
You can find it on the owners GitHub:
https://github.com/AArnott/dotnetopenid
This is more like a conceptual question. When to use Model Binding (in ASP.NET MVC Framework) and when to inject objects using IoC (lets say Autofac here) ?
One specific scenario is like lets say, I have the following action method
public ActionResult EditProfile(string UserId)
{
// get user object from repository using the the UserId
// edit profile
// save changes
// return feedback
}
In the above scenario, is it possible to inject a user object to action method such that it automatically gets the user object using the UserId ? The resulting signature being:
public ActionResult EditProfile(UserProfile userObj) //userObj injected *somehow* to automatically retreive the object from repo using UserId ?
Sorry if it all doesn't makes sense. It`s my first time using IoC.
EDIT:
This is the way to do it > http://buildstarted.com/2010/09/12/custom-model-binders-in-mvc-3-with-imodelbinder/
You can do what you need using a custom action filter. By overriding OnActionExecuting, we have access to the route data, and the action parameters of the action that will be executed. Given:
public class BindUserProfileAttribute : ActionFilterAttribute
{
public override OnActionExecuting(FilterContext filterContext)
{
string id = (string)filterContext.RouteData.Values["UserId"];
var model = new UserProfile { Id = id };
filtextContext.ActionParameters["userObj"] = model;
}
}
This attribute allows us to create the parameters that will be passed into the action, so we can load the user object at this point.
[BindUserProfile]
public ActionResult EditProfile(UserProfile userObj)
{
}
You'll probably need to get specific with your routes:
routes.MapRoute(
"EditProfile",
"Account/EditProfile/{UserId}",
new { controller = "Account", action = "EditProfile" });
In MVC3 we get access to the new IDepedencyResolver interface, which allows us to perform IoC/SL using whatever IoC container or service locator we want, so we can push a service like a IUserProfileFactory into your filter, to then be able to create your UserProfile instance.
Hope that helps?
Model binding is used for your data. Dependency injection is used for your business logic.
I need to add some extension points to our existing code, and I've been looking at MEF as a possible solution. We have an IRandomNumberGenerator interface, with a default implementation (ConcreteRNG) that we would like to be swappable. This sounds like an ideal scenario for MEF, but I've been having problems with the way we instantiate the random number generators. Our current code looks like:
public class Consumer
{
private List<IRandomNumberGenerator> generators;
private List<double> seeds;
public Consumer()
{
generators = new List<IRandomNumberGenerator>();
seeds = new List<double>(new[] {1.0, 2.0, 3.0});
foreach(var seed in seeds)
{
generators.Add(new ConcreteRNG(seed));
}
}
}
In other words, the consumer is responsible for instantiating the RNGs it needs, including providing the seed that each instance requires.
What I'd like to do is to have the concrete RNG implementation discovered and instantiated by MEF (using the DirectoryCatalog). I'm not sure how to achieve this. I could expose a Generators property and mark it as an [Import], but how do I provide the required seeds?
Is there some other approach I am missing?
Currently there isn't a direct way to do this in MEF but the MEF team is considering support for this in v.Next. You essentially want to create multiple instances of the same implementation which is traditially done using a Factory pattern. So one approach you could use is something like:
public interface IRandomNumberGeneratorFactory
{
IRandomNumberGenerator CreateGenerator(int seed);
}
[Export(typeof(IRandomNumberGeneratorFactory))]
public class ConcreateRNGFactory : IRandomNumberGeneratorFactory
{
public IRandomNumberGenerator CreateGenerator(int seed)
{
return new ConcreateRNG(seed);
}
}
public class Consumer
{
[Import(typeof(IRandomNumberGeneratorFactory))]
private IRandomNumberGeneratorFactory generatorFactory;
private List<IRandomNumberGenerator> generators;
private List<double> seeds;
public Consumer()
{
generators = new List<IRandomNumberGenerator>();
seeds = new List<double>(new[] {1.0, 2.0, 3.0});
foreach(var seed in seeds)
{
generators.Add(generatorFactory.CreateGenerator(seed));
}
}
}
MEF preview 8 has experimental support for this, though it is not yet included in System.ComponentModel.Composition.dll. See this blog post for more information.
You'll have to download the MEF sources and build the solution. In the Samples\DynamicInstantiation folder you'll find the assembly Microsoft.ComponentModel.Composition.DynamicInstantiation.dll. Add a reference to this assembly and add a dynamic instantiation provider to your container like this:
var catalog = new DirectoryCatalog(".");
var dynamicInstantiationProvider = new DynamicInstantiationProvider();
var container = new CompositionContainer(catalog, dynamicInstantiationProvider);
dynamicInstantiationProvider.SourceProvider = container;
Now your parts will be able to import a PartCreator<Foo> if they need to dynamically create Foo parts. The advantage over writing your own factory class is that this will transparently take care of the imports of Foo, and the imports' imports, etcetera.
edit:
in MEF Preview 9 PartCreator was renamed to ExportFactory but it is only included in the silverlight edition.
in MEF 2 Preview 2, ExportFactory became included for the desktop edition. So ExportFactory will probably be part of the next .NET framework version after .NET 4.0.
I believe this is what the Lazy Exports feature is for. From that page:
[Import]
public Export<IMessageSender> Sender { get; set; }
In this case you are opt-in for delaying this instantiation until you actually need the implementation instance. In order to request the instance, use the method [Export.GetExportedObject()]. Please note that this method will never act as a factory of implementations of T, so calling it multiple times will return the same object instance returned on the first call.