Multiple Zend_Mail configurations in application.ini - zend-mail

I'm am using Zend Framework.
I need to put multiple mail configurations in application.ini for Zend_Mail (using Zend_Application_Resource_Mail). Is it possible to do this using the standard classes in Zend Framework or do I need to create my own class?
I am using the latest stable version of Zend Framework.
Thanks for the answers

It does not appear to be possible to set multiple configurations for Zend_Mail with Zend_Application_Resource_Mail.
You could add the various configurations to application.ini but you will have to write your own class/functions to make the desired configuration active.
The things that are set by Zend_Application_Resource_Mail that you will have to override are Zend_Mail::setDefaultTransport($newTransport);, Zend_Mail::setDefaultReplyTo($email);, and Zend_Mail::setDefaultFrom($email);.
I tested something and found an easy thing you can do.
Set up your different configurations like this in application.ini:
mail_config.mail_test.transport.type = smtp
mail_config.mail_test.transport.host = "smtp.example.com"
mail_config.mail_test.transport.auth = login
mail_config.mail_test.transport.username = myUsername
mail_config.mail_test.transport.password = myPassword
mail_config.mail_test.defaultFrom.email = john#example.com
mail_config.mail_test.defaultFrom.name = "John Doe"
mail_config.mail_test.defaultReplyTo.email = Jane#example.com
mail_config.mail_test.defaultReplyTo.name = "Jane Doe"
Note how we are setting up options under mail_config. This will be the set of options to apply. mail_test is an example configuration. You can have multiple by setting mail_config.mail_test2, mail_config.corporate_mail, or mail_config.production etc.
Next, create an empty class that extends from Zend_Application_Resource_Mail. Preferably, it should be named and placed so it can be autoloaded.
The class:
<?php
class Application_Service_MailSettings extends Zend_Application_Resource_Mail { }
Now, here is how to override the default mail configuration easily with something else.
This example assumes you are in a controller:
// get the bootstrap, so we can get mail_config options
$bootstrap = $this->getInvokeArg('bootstrap');
$options = $bootstrap->getOption('mail_config');
// initialize the resource loader with the options from mail_config.mail_test
$mailSettings = new Application_Service_MailSettings($options['mail_test']);
$mailSettings->init(); // call init() so the settings are applied
// now the default transport, from, and reply to are set using mail_config.mail_test options.
// to use a different set of options, just do
// $mailSettings = new Application_Service_MailSettings($options['other_config');
This should accomplish what you want with very little new code.

Related

Dependency Injection Access While Configuring Service Registrations in asp.net Core (3+)

I have cases, where I want to configure services based on objects which are registered in the dependency injection container.
For example I have the following registration for WS Federation:
authenticationBuilder.AddWsFederation((options) =>{
options.MetadataAddress = "...";
options.Wtrealm = "...";
options.[...]=...
});
My goal in the above case is to use a configuration object, which is available via the DI container to configure the WsFederation-middleware.
It looks to me that IPostConfigureOptions<> is the way to go, but until now, I have not found a way to accomplish this.
How can this be done, or is it not possible?
See https://andrewlock.net/simplifying-dependency-injection-for-iconfigureoptions-with-the-configureoptions-helper/ for the I(Post)ConfigureOptions<T> way, but I find that way too cumbersome.
I generally use this pattern:
// Get my custom config section
var fooSettingsSection = configuration.GetSection("Foo");
// Parse it to my custom section's settings class
var fooSettings = fooSettingsSection.Get<FooSettings>()
?? throw new ArgumentException("Foo not configured");
// Register it for services who ask for an IOptions<FooSettings>
services.Configure<FooSettings>(fooSettings);
// Use the settings instance
services.AddSomeOtherService(options => {
ServiceFoo = fooSettings.ServiceFoo;
})
A little more explicit, but you have all your configuration and DI code in one place.
Of course this bypasses the I(Post)ConfigureOptions<T> entirely, so if there's other code that uses those interfaces to modify the FooSettings afterwards, my code won't notice it as it's reading directly from the configuration file. Given I control FooSettings and its users, that's no problem for me.
This should be the approach if you do want to use that interface:
First, register your custom config section that you want to pull the settings from:
var fooSettingsSection = configuration.GetSection("Foo");
services.Configure<FooSettings>(fooSettingsSection);
Then, create an options configurer:
public class ConfigureWSFedFromFooSettingsOptions
: IPostConfigureOptions<Microsoft.AspNetCore.Authentication.WsFederation.WsFederationOptions>
{
private readonly FooSettings _fooSettings;
public ConfigureWSFedFromFooSettingsOptions(IOptions<FooSettings> fooSettings)
{
_fooSettings = fooSettings.Value;
}
public void Configure(WsFederationOptions options)
{
options.MetadataAddress = _fooSettings.WsFedMetadataAddress;
options.Wtrealm = _fooSettings.WsFedWtRealm;
}
}
And finally link the stuff together:
services.AddTransient<IPostConfigureOptions<WsFederationOptions>, ConfigureWSFedFromFooSettingsOptions>();
The configurer will get your IOptions<FooSettings> injected, instantiated from the appsettings, and then be used to further configure the WsFederationOptions.

How to set Attribute to PDO connection in Codeigniter

How to set attributes (PDO::ATTR_ERRMODE) on the PDO database handle in Codeigniter?
I think a better option is to use a MY_Model (which you then extend and this is available then across the application) and define something like this in the construct:
$this->db->conn_id->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
Note conn_id allows you to access the main PDO object.
There are two ways:
1. The lazy (hacky) way
Add to the following code into system/core/database/drivers/pdo/pdo_driver.php (in CI 3):
public function db_connect($persistent = FALSE)
{
$this->options[PDO::ATTR_PERSISTENT] = $persistent;
// Added code start
$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
// Added code end
try
{
return new PDO($this->dsn, $this->username, $this->password, $this->options);
...
}
2. The right way
Extend Database Driver and add the same line
Note: If you will set PDO::ERRMODE_EXCEPTION in Codeigniter it will show exception errors even in Production environment.

module creation in suiteCRM

I am using SuiteCRM ( Sugar CRM 6.x community edition ) & want to create a custom login page and after successful login I want to redirect based on user type
tried to create some modules but there is no clear documentation except few of useful links, below are my queries :
Can we create custom modules without using module builder, if yes then what would be steps?
Do we need to write module in /module folder or /custom/module folder or on both place?
any link is also appreciated.
You can create a custom Login Page by modfying "modules/Users/login.tpl"
Custom Modules can be created through Modulebuilder or manually.
When creating modules manually it's important to use the right names.
The easiest way is a Plural name for the folder, table and Module and a singular name for the class.
Manual steps:
You need a Folder in modules/ named like you module (i.e. CAccounts)
In this folder you need a file named like the class (i.e CAccount.php) with something like that as content:
require_once('data/SugarBean.php');
require_once('include/utils.php');
class CAccount extends SugarBean{
var $table_name = 'caccounts';
var $object_name = 'CAccount';
var $module_dir = 'CAccounts';
var $new_schema = true;
var $name;
var $created_by;
var $id;
var $deleted;
var $date_entered;
var $date_modified;
var $modified_user_id;
var $modified_by_name;
function CAccount (){
parent::SugarBean();
}
function get_summary_text(){
return $this->name;
}
function bean_implements($interface)
{
switch($interface)
{
case 'ACL':return true;
}
return false;
}
}
In this folder you need a vardefs.php file:
$dictionary['CAccount'] = array(
'table'=>'caccounts',
'audited'=>false,
'fields'=>array (
//Your fielddefs here
)
);
require_once('include/SugarObjects/VardefManager.php');
VardefManager::createVardef('CAccounts','CAccount', array('basic'));
For the language and metadata folders look at any other module.
Next is a file at "custom/Extension/application/Ext/Include/CAccounts.include.php"
$moduleList[] = 'CAccounts';
$beanList['CAccounts'] = 'CAccount';
$beanFiles['CAccount'] = 'modules/CAccounts/CAccount.php';
A language file for the module name must be in "custom/Extension/application/Ext/Language/"
$app_list_strings['moduleList']['CAccounts'] = 'Custom Accounts';
To display the Module in your tabs you need to use "rebuild and repair" and then the "Display Modules and Subpanels" option in the admin menu.
For a custom module you don't need the "custom/" folder structure. Files there will be used by sugar if provided, but often there's no need for that in a custom module.
Guides about the Module Framework can be found on the sugarcrm support site:
http://support.sugarcrm.com/02_Documentation/04_Sugar_Developer/Sugar_Developer_Guide_6.5/03_Module_Framework

How to configure multiple sitemaps using MVCSiteMapProvider v4 with StructureMap DI

The problem, essentially, is that I can't get my sitemap config to support multiple sitemaps. It's always looking for "default" even when I name my instances and request another. Now for the background.
I've been pouring over the docs for the new implementation of MVCSiteMapProvider. They are now using Dependency Injection to configure the SiteMapProvider. We have an existing StructureMap DI implementation, so I followed the instructions and added, in our case
ObjectFactory.Configure(x =>
{
...
x.AddRegistry<MvcSiteMapProviderRegistry>();
...
});
Then I started tweaking the MvcSiteMapProviderRegistry.cs file to implement my multiple sitemap scenario. I have multiple site map files, either will work as long as it's called "default". If I remove the "default" item then it breaks and complains that "default" is missing. Which I assume is because it can't find my instance. Here's how I have them defined. I suspect the problem is somewhere in here... the loader which it says I have to configure in the Global.asax is looking for ISiteMapLoader but I'm adding my multiple configuration to SiteMapBuilderSet... anyway here's the code.
// Register the sitemap builder
string absoluteFileName = HostingEnvironment.MapPath("~/Main.sitemap");
string absoluteFileName2 = HostingEnvironment.MapPath("~/Test.sitemap");
var xmlSource = this.For<IXmlSource>().Use<FileXmlSource>()
.Ctor<string>("fileName").Is(absoluteFileName);
var reservedAttributeNameProvider = this.For<ISiteMapXmlReservedAttributeNameProvider>()
.Use<SiteMapXmlReservedAttributeNameProvider>()
.Ctor<IEnumerable<string>>("attributesToIgnore").Is(new string[0]);
var builder = this.For<ISiteMapBuilder>().Use<CompositeSiteMapBuilder>()
.EnumerableOf<ISiteMapBuilder>().Contains(y =>
{
y.Type<XmlSiteMapBuilder>()
.Ctor<ISiteMapXmlReservedAttributeNameProvider>().Is(reservedAttributeNameProvider)
.Ctor<IXmlSource>().Is(xmlSource);
y.Type<ReflectionSiteMapBuilder>()
.Ctor<IEnumerable<string>>("includeAssemblies").Is(includeAssembliesForScan)
.Ctor<IEnumerable<string>>("excludeAssemblies").Is(new string[0]);
y.Type<VisitingSiteMapBuilder>();
});
var xmlSource2 = this.For<IXmlSource>().Use<FileXmlSource>()
.Ctor<string>("fileName").Is(absoluteFileName2);
var builder2 = this.For<ISiteMapBuilder>().Use<CompositeSiteMapBuilder>()
.EnumerableOf<ISiteMapBuilder>().Contains(y =>
{
y.Type<XmlSiteMapBuilder>()
.Ctor<ISiteMapXmlReservedAttributeNameProvider>().Is(reservedAttributeNameProvider)
.Ctor<IXmlSource>().Is(xmlSource2);
y.Type<ReflectionSiteMapBuilder>()
.Ctor<IEnumerable<string>>("includeAssemblies").Is(includeAssembliesForScan)
.Ctor<IEnumerable<string>>("excludeAssemblies").Is(new string[0]);
y.Type<VisitingSiteMapBuilder>();
});
// Configure the builder sets
this.For<ISiteMapBuilderSetStrategy>().Use<SiteMapBuilderSetStrategy>()
.EnumerableOf<ISiteMapBuilderSet>().Contains(x =>
{
/* x.Type<SiteMapBuilderSet>()
.Ctor<string>("instanceName").Is("default")
.Ctor<bool>("securityTrimmingEnabled").Is(securityTrimmingEnabled)
.Ctor<bool>("enableLocalization").Is(enableLocalization)
.Ctor<ISiteMapBuilder>().Is(builder)
.Ctor<ICacheDetails>().Is(cacheDetails);*/
/*
x.Type<SiteMapBuilderSet>()
.Ctor<string>("instanceName").Is("MainSiteMapProvider")
.Ctor<bool>("securityTrimmingEnabled").Is(securityTrimmingEnabled)
.Ctor<bool>("enableLocalization").Is(enableLocalization)
.Ctor<ISiteMapBuilder>().Is(builder)
.Ctor<ICacheDetails>().Is(cacheDetails);*/
x.Type<SiteMapBuilderSet>()
.Ctor<string>("instanceName").Is("TestSiteMapProvider")
.Ctor<bool>("securityTrimmingEnabled").Is(securityTrimmingEnabled)
.Ctor<bool>("enableLocalization").Is(enableLocalization)
.Ctor<ISiteMapBuilder>().Is(builder2)
.Ctor<ICacheDetails>().Is(cacheDetails);
});
In my global.asax.cs I added
MvcSiteMapProvider.SiteMaps.Loader = Resolver.Get<ISiteMapLoader>();
and to reference in my view I have
#Html.MvcSiteMap("TestSiteMapProvider").Menu(false, true, true)
but it must not be able to find "TestSiteMapProvider" because it always displays "default" or complains if it doesn't exist.
I also thought it might have something to do with the Cache, as I see the filename referenced there, but I don't know how to add multiple instances to the cache, so I just disabled it. I'm really not doing anything fancy with my sitemaps anyway, and this whole thing is really feeling like massive overkill just to get some flippin automatic breadcrumbs!
Apparently there was another help doc that I wasn't aware of. I had completed all of the steps thus far properly, but I also needed to implement ISiteMapCacheKeyGenerator.
See this doc (which wasn't named this when I started.)
https://github.com/maartenba/MvcSiteMapProvider/wiki/Multiple-Sitemaps-in-One-Application

What options do I have for automating bindings with NInject

Rather than manually having to bind every class, what methods and patterns, if any, are recommended for automatically setting up bindings?
For example, the vast majority of bindings simply look like this:
Bind<ICustomerRepository>.To<CustomerRepository>();
Once modules get large, you can end up with 100s of bindings that all look exactly the same. Can this be automated?
check out the conventions extension:
https://github.com/ninject/ninject.extensions.conventions
using (IKernel kernel = new StandardKernel())
{
var scanner = new AssemblyScanner();
scanner.From(Assembly.GetExecutingAssembly());
scanner.BindWith<DefaultBindingGenerator>();
kernel.Scan(scanner);
var instance = kernel.Get<IDefaultConvention>();
instance.ShouldNotBeNull();
instance.ShouldBeInstanceOf<DefaultConvention>();
}