Coldfusion 9 ORM Mapping issue - orm

I have an issue with CF9 ORM mapping.
I get the following error from time to time (yes, it works fine most of the time),
Mapping for component model.Pubs not found. Either the mapping for this component is missing or the application must be restarted to generate the mapping.
ORM definition in Application.cfc
<cfscript>
this.datasource = "Pubs";
this.ormenabled = true;
this.ormsettings= {
dialect="MicrosoftSQLServer",
dbcreate="update",
eventhandling="true"
};
</cfscript>
<cfset this.mappings["/model"] = getDirectoryFromPath(getCurrentTemplatePath()) & "model" />
The only way to fix it is to refresh the ORM couple of time, which is by hitting ?init=true on Application.cfc. It is still a temporary solution, but I need to know the root cause of it and fix it.
<cfscript>
if(structKeyExists(url, "init")) { ormReload(); applicationStop(); location('index.cfm?reloaded=true'); }
Please advise.
Thanks!

I also had your problem, but now it works fine. First, if you don't set ormsettings.cfclocation, ColdFusion does this:
If it is not set, ColdFusion looks at the application directory, its sub-directories, and its mapped directories to search for persistent CFCs. (see Spec)
This is error prone, because you never know what ColdFusion finds in all that directories.
When you add cfclocation to your example it should work:
this.ormsettings= {
cfclocation = ["/model", "/other/entities", "/more/other/entites"]
}
There is a lot of discussion out there, about how to specify the paths for cfclocation. For me, that way works.
But the first element of my cfclocation is always an application mapping, like your this.mappings["/model"]. I have not tested it with webserver aliases or CFCs in the webroot, without mapping. You should also avoid colliding namespaces, like a "model" directory in the webroot, while having a "/model" mapping.
Good luck:)

Okay, thank you both #Henry and #Walter for your comments. They were the lead toward the right solution.
Here's what I did to make sure it's stable ALL the time.
I used one folder (location) for all ORM CFCs. There used to be a "model" folder for each section. Sections are sibling folders under one root and share the same Application.cfc.
I changed that to ONE root level folder for all CFCs, ie: /root/ormmodel
On the /root/Application.cfc, I adjusted the following code
<cfset application.mappings["/ormmodel"] = expandPath("/root/ormmodel") />
and
this.ormsettings= {
cfclocation = ["ormmodel"],
autogenmap = true,
...
eventhandling="true"
};
Notice the missing "/" in the cfclocation value.
On calling for model components, I changed the code from pub = new ormmodel.Pubs() to
pub = EntityNew("Pubs");
On an unrelated point, I've changed my components name to camelCase naming and avoided special characters like underscores and dashes.
I hope this would be helpful and save someone else hours of frustration and suspense.
Happy coding!

Related

How to pass the scopes I need in the microsoftTeams.authentication.authenticate() method

After creating a teams-tab-app using the vscode teams toolkit, I see that in the default auth-start.html file the script tries to extract the scopes from the URL (that was constructed by the microsoftTeams.authentication.authenticate() method), however I don't see any reference in the documentation on how to pass these scopes in this method.
Does anyone know how to pass these scopes?
I've wondered about this myself when looking at a toolkit, but I haven't used it for any production systems so never bothered to look too deep. I do see that in useTeamsFx.tsx is where it's doing the redirect to startLoginPageUrl, so presumably you need to set REACT_APP_START_LOGIN_PAGE_URL to be the path to the auth-start.html, so you could set it to include a querystring as well. It needs the app Id so you'd need to set that as well, but the useTeamsFx also wants REACT_APP_CLIENT_ID which you'd set as well. As a result, it might make sense to store the scopes you want in your code or in an environment variable as well, and then compose the value you send to initiateLoginEndpoint. Basically, instead of
var startLoginPageUrl = process.env.REACT_APP_START_LOGIN_PAGE_URL;
...
initiateLoginEndpoint: startLoginPageUrl
...
you might instead make it
var startLoginPageUrl = process.env.REACT_APP_START_LOGIN_PAGE_URL;
var scopes = process.env.REACT_APP_SCOPES; // <-- this is added
...
initiateLoginEndpoint: `${startLoginPageUrl}?clientId=${clientId}&scope=${scopes}`
...
but this is untested, so no guarantees.
On a separate but related note, in my sample project, in auth-start, it refers to a very old version of MicrosoftTeams.min.js (v 1.6, and current is 1.11). I might just have a very old Teams Toolkit, but maybe not...

How to apply metadata to all files in a content directory

I have a content directory called foo and I want all files under that directory to have an extra metadata item foovar: default, unless explicitly overridden in the file header. I think I'm supposed to do this with EXTRA_PATH_METADATA, but I can't figure out what incantation it wants.
(for my current use case I'm trying to apply template: sometemplate within this dir, but I'm interested in solving the general case as it would make several related headaches go away)
I think what you're looking for is actually DEFAULT_METADATA. Check out this portion of the documentation:
DEFAULT_METADATA = {}
The default metadata you want to use for all articles and pages.
So, in your case it might look something like this in your config file:
DEFAULT_METADATA = {'foovar': 'default'}
Then to assign your custom template(s), see this portion of the documentation.
This wasn't possible at the time I asked. I've since sent the devs a PR adding support, and it's been merged to master. Presumably it will go out in the next release. It makes EXTRA_PATH_METADATA recursive, so you can apply settings to a subdir like this:
EXTRA_PATH_METADATA = {'dirname/subdir': {'status': 'hidden'}}

phpexcel pdf rendering library has not been defined

After trying and failing to generate PDFs with PHPExcel 1.7.6 (out of memory errors), I upgraded to 1.7.8. I can't for the life of me figure out how to get it working. I've tried tcPDF and mPDF, and it's the same for both.
Putting it back to Excel output, I can see I'm setting the path correctly. All I can get is "PDF Rendering library has not been defined", and I can't figure out what it wants - I've tried 'mPDF5.4', 'MPDF54' (the actual name of the folder itself), 'mpdf', 'mpdf.php'...same each time.
I've been using PHPExcel for over a year, so I'm not entirely new to it. I've lost way more time than I care to admit on this problem, and I haven't found this problem described anywhere, so I'm feeling more than a little stupid that I appear to be the only one that can't figure this out.
The actual code I'm using is the following:
ini_set('include_path', ini_get('include_path').'\\Classes\\');
$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;
$rendererLibrary = 'mPDF5.4';
$rendererLibraryPath = ini_get('include_path') . $rendererLibrary;
(That is, pretty well a copy of the example code.)
In the interest of completeness, the headers I'm using are
echo header("Content-Type: application/pdf");
echo header("Content-Disposition: attachment; filename=".$filename.".pdf" );
echo header('Cache-Control: max-age=0');
These near the top of the file, naturally.
Near the end of the file, the output code is
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');
$objWriter->save('php://output');
I got it working. Much as I'd like to say I had a breakthrough moment and understand it perfectly, I have no idea how I got it to work. However, in hopes that it might help someone, let me lay out what I did.
I'm running XAMPP on Windows. My file structure has the folder for PHPExcel itself in xampp\php\PEAR\Classes. domPDF is in the same folder, and I renamed it 'dompdf'.
For reasons I no longer recall, I set the include path like so:
ini_set('include_path', ini_get('include_path').'\\Classes\\');
To set the rendering path, I used the following:
$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;
$rendererLibrary = 'dompdf';
$rendererLibraryPath = ini_get('include_path') . $rendererLibrary;
For the actual writer creation, I'm using the following:
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');
$objWriter->save($path.$fullFileName);
One thing I noticed that may have made things different was doing this:
// include 'PHPExcel/Writer/Excel2007.php';
That is, unlike everything I've done in PHPExcel, I'm not including anything from the Writer folder at all. Best I can remember, that's all that's different this time versus a week ago when I asked the question. Once I'd grabbed the 01simple-download-pdf.php file from the Tests folder in 1.7.8, it was mostly a matter of copying the code from it and tweaking it to my paths.
To summarize, leave $rendererName alone. The $rendererLibrary is the name of the folder that contains the library, 'dompdf' in my case. The $rendererLibraryPath is literally setting the path to that folder, so it ends with the path that contains the pdf library folder.
It should be obvious that I'm no uber-leet hax0r, but SO has answered many, many programming questions for me. I'm hoping this helps someone else, so they're not wasting hours like I did.
The PHPOffice contains also PHPWord. I have had the same error message with PHPWord. This is for LINUX. A replacement of 'PhpWord' by 'PhpExcel' should do the job for this case. You must modify the path $rendererLibraryPath to your needs.
$rendererName = \PhpOffice\PhpWord\Settings::PDF_RENDERER_DOMPDF;
$rendererLibraryPath = realpath(__DIR__ . '/../../../../../dompdf-0.6.1');
\PhpOffice\PhpWord\Settings::setPdfRenderer($rendererName, $rendererLibraryPath);
$objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'PDF');
$objWriter->save('helloWorld.pdf');
If you are getting this error and you have set the correct path to the TCPDF or DOMPDF folder (you do not have to write the full path), then also make sure you have these lines:
if (!PHPExcel_Settings::setPdfRenderer(
$rendererName,
$rendererLibraryPath
)) {
die(
'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .
EOL .
'at the top of this script as appropriate for your directory structure'
);
}

ASP.net MVC: Execute Razor from DB String?

I was thinking about giving end users the ability to drop Partial Views (controls) into the information being stored in the database. Is there a way to execute a string I get from the database as part of the Razor view?
Update (I forgot all about this)
I had asked this question previously (which lead me to create RazorEngine) Pulling a View from a database rather than a file
I know of at least two: RazorEngine, MvcMailer
I have a bias towards RazorEngine as it's one that I've worked on but I have a much simpler one at Github called RazorSharp (though it only supports c#)
These are all pretty easy to use.
RazorEngine:
string result = RazorEngine.Razor.Parse(razorTemplate, new { Name = "World" });
MvcMailer
I haven't used this one so I can't help.
RazorSharp
RazorSharp also supports master pages.
string result = RazorSharp.Razor.Parse(new { Name = "World" },
razorTemplate,
masterTemplate); //master template not required
Neither RazorSharp, nor RazorEngine support any of the Mvc helpers such as Html and Url. Since these libraries are supposed to exist outside of Mvc and thus require more work to get them to work with those helpers. I can't say anything about MvcMailer but I suspect the situation is the same.
Hope these help.

DataContext Doesn't Exist in Dynamic Data Project?

This is really annoying...and I know it is something extremely simple...
1. I create a new Dynamic Data project.
2. I add a LINQ-to-SQL class and drag and drop some tables onto the class.
3. I open the global.asax.vb and uncomment the line:
DefaultModel.RegisterContext(GetType(YourDataContext), New ContextConfiguration() With {.ScaffoldAllTables = True})
I remove YourDataContext and replace it with the DataContext from my LINQ-to-SQL class:
DefaultModel.RegisterContext(GetType(NorthwindDataContext), New ContextConfiguration() With {.ScaffoldAllTables = True})
I then try to debug/build/etc. and receive the following error:
Type 'NorthwindDataContext' is not defined
Why is it not defined? It seems like its not recognizing I created the DBML file.
This is a very strange issue and I am still not sure that I have entirely fixed the issue. But, here is what I think I have learned:
1. If you are creating a New Project in VS2010 you must place the LINQ-to-SQL DBML file in the root project directory.
2. If you are creating a new Web Site in VS2010 you must place the LINQ-to-SQL DBML file in a newly created App_Code directory.
3. If you place it in the wrong place, scrap the project and start over - it doesn't seem to work even if you move the files to the correct location or recreate them in the correct location.
Dave.
Does your project compile? I am guessing you are missing the namespace to your data context. Something like this:
model.RegisterContext(typeof(MyApp.MyNamespace.NorthwindDataContext),
new ContextConfiguration() { ScaffoldAllTables = true });