<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ben Gribaudo</title>
	<atom:link href="http://bengribaudo.com/feed" rel="self" type="application/rss+xml" />
	<link>http://bengribaudo.com</link>
	<description>&#34;Come ye, and let us walk in the light of the LORD.&#34; Isaiah 2:5</description>
	<lastBuildDate>Mon, 06 Feb 2012 16:03:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>SSRS &#8211; Updating Linked Report Page Properties</title>
		<link>http://bengribaudo.com/blog/2012/01/30/1851/ssrs-updating-linked-report-page-properties</link>
		<comments>http://bengribaudo.com/blog/2012/01/30/1851/ssrs-updating-linked-report-page-properties#comments</comments>
		<pubDate>Mon, 30 Jan 2012 20:01:35 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[SSRS]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=1851</guid>
		<description><![CDATA[Page property changes made to Microsoft SQL Server Reporting Services (SSRS) reports are not passed on to linked reports. For example, changing a parent report&#8217;s page size from letter to legal will not change child linked reports&#8217; page sizes to &#8230; <a href="http://bengribaudo.com/blog/2012/01/30/1851/ssrs-updating-linked-report-page-properties">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Page property changes made to Microsoft SQL Server Reporting Services (SSRS) reports are not passed on to linked reports. For example, changing a parent report&#8217;s page size from letter to legal will not change child linked reports&#8217; page sizes to legal.</p>
<p>Sometimes, it&#8217;s desirable to synchronize child report page settings to their parents. Brian Welcker posted a <a href="http://blogs.msdn.com/b/bwelcker/archive/2005/09/28/474898.aspx" target="_blank">code sample showing how to automate this property copying</a> using the now old-style .Net 2.0 Web Reference approach. Let&#8217;s implement the same functionality using the modern (though, unfortunately, more verbose) Service Reference approach.<span id="more-1851"></span></p>
<p>For our example, we&#8217;ll use C# executed in the context of a <em>Console Application</em>.</p>
<h2>Creating the Service Reference</h2>
<p>In <em>Solutions Explorer</em>, right-click on the project&#8217;s <em>References</em> folder and select <em>Add Service Reference</em>. In the dialog that&#8217;s displayed, input your reporting server&#8217;s web service URL, then click <em>Go</em>. Once the service information fetching completes, click <em>OK</em>. (If you&#8217;d like, adjust the namespace to be used for the service proxy classes before clicking <em>OK</em>.)</p>
<h2>Code</h2>
<pre class="brush:csharp">using System;
using System.ServiceModel;
using rs = PropertySync.ReportingService;

namespace PropertySync
{
    class Program
    {
        static void Main(string[] args)
        {
            var service = new rs.ReportingService2010SoapClient();

            // Retrieve a list of reports.
            rs.CatalogItem[] reports = null;
            service.ListChildren(new rs.TrustedUserHeader(), "/", true, out reports);

            // List of properties to copy from parent to linked reports.
            var requestedProperties = new rs.Property[] {
                new rs.Property { Name = "PageHeight" },
                new rs.Property { Name = "PageWidth" },
                new rs.Property { Name = "TopMargin" },
                new rs.Property { Name = "BottomMargin" },
                new rs.Property { Name = "LeftMargin" },
                new rs.Property { Name = "RightMargin" }
            };

            foreach (var report in reports) {
                Console.Write("{0} ({1})", report.Name, report.Path);

                if (report.TypeName == "LinkedReport") {
                    string parentReportLink = null;
                    service.GetItemLink(new rs.TrustedUserHeader(), report.Path, out parentReportLink);

                    // Fetch interested property values from parent report.
                    ReportingService.Property[] parentValues = null;
                    service.GetProperties(new rs.ItemNamespaceHeader(), new rs.TrustedUserHeader(), parentReportLink, requestedProperties, out parentValues);

                    // Set the child report's properties to the just-fetched values.
                    service.SetProperties(new rs.TrustedUserHeader(), report.Path, parentValues);
                    Console.WriteLine(" -- properties updated from {0}", parentReportLink);
                } else {
                    Console.WriteLine(" -- non-linked - skipped");
                }
            }
        }
    }
}</pre>
<p>Compile and run. If the application executes successfully, we&#8217;re done!</p>
<h2>Configuring the Binding</h2>
<p>If the program fails with a security error (perhaps a MessageSecurityException), you probably need to adjust your web service binding configuration. Your code is probably trying to execute web service methods anonymously (without passing authentication credentials) while SSRS is probably configured to require client authentication.</p>
<p>The exact binding settings required depend on your server&#8217;s configuration—detailing the various possibilities is beyond the scope of this article. A common client configuration scenario is illustrated below:</p>
<pre class="brush:csharp">var binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

var endpointUri = "http://reporting/ReportServer_SQL/ReportService2010.asmx";
var service = new rs.ReportingService2010SoapClient(binding, new EndpointAddress(endpointUri));
service.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;</pre>
<p>If you are using integrated (Windows) security, you may need to run your application as an administrator in order for credentials to be passed. (Hint: if you are launching the program from within Microsoft Visual Studio, run Visual Studio as an administrator.)</p>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2012/01/30/1851/ssrs-updating-linked-report-page-properties/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP $_POST Empty After Setting post_max_size &amp; upload_max_filesize</title>
		<link>http://bengribaudo.com/blog/2012/01/27/1801/php-_post-empty-after-setting-post_max_size-upload_max_filesize</link>
		<comments>http://bengribaudo.com/blog/2012/01/27/1801/php-_post-empty-after-setting-post_max_size-upload_max_filesize#comments</comments>
		<pubDate>Fri, 27 Jan 2012 19:25:33 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=1801</guid>
		<description><![CDATA[$_POST was empty! Firebug showed that the web browser was submitting the form&#8217;s data to the server. Yet, for some reason, PHP was not putting the data into the $_POST array. If I switched the form&#8217;s action from POST to &#8230; <a href="http://bengribaudo.com/blog/2012/01/27/1801/php-_post-empty-after-setting-post_max_size-upload_max_filesize">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>$_POST was empty! <a href="http://getfirebug.com/" target="_blank">Firebug</a> showed that the web browser was submitting the form&#8217;s data to the server. Yet, for some reason, PHP was not putting the data into the $_POST array. If I switched the form&#8217;s action from POST to GET, PHP properly populated $_GET. What was wrong with $_POST?!<span id="more-1801"></span></p>
<p>Shortly prior to this problem appearing, I had set a couple of configuration directives in a <a href="http://wiki.dreamhost.com/Php.ini#PHP_5.3" target="_blank">php.ini file fragment</a>—something like this:</p>
<pre class="brush:shell">post_max_size	        2GB
upload_max_filesize     2GB</pre>
<p>Looks correct, doesn&#8217;t it? Nope!</p>
<p>I learned the hard way that PHP uses <a href="http://us3.php.net/manual/en/faq.using.php#faq.using.shorthandbytes" target="_blank"><em>single</em> letter abbreviations</a> to indicate kilobytes (K), megabytes (M) and gigabytes (G)! Dropping the &#8220;B&#8221; off of each &#8220;GB&#8221; fixed the problem—PHP went back to properly populating $_POST.</p>
<p>Interestingly, <a href="http://php.net/manual/en/function.phpinfo.php" target="_blank">phpinfo()</a> and <a href="http://php.net/manual/en/function.ini-get.php" target="_blank">ini_get()</a> won&#8217;t necessarily cough about the extraneous &#8220;B&#8221; being present. This deceptive acceptance of incorrectly formatted configuration values can complicate debugging.</p>
<p><em>Thanks to <a href="http://stackoverflow.com/a/1284934/117424" target="_blank">Stack Overflow</a> for providing the answer I needed to solve this perplexing $_POST issue!</em></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2012/01/27/1801/php-_post-empty-after-setting-post_max_size-upload_max_filesize/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rake Package Task Fails with Status 127 on Windows</title>
		<link>http://bengribaudo.com/blog/2012/01/25/1771/rake-package-task-fails-with-status-127-on-windows</link>
		<comments>http://bengribaudo.com/blog/2012/01/25/1771/rake-package-task-fails-with-status-127-on-windows#comments</comments>
		<pubDate>Wed, 25 Jan 2012 18:44:47 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Rake]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=1771</guid>
		<description><![CDATA[The other day, I tried running a Rake Package task on a Windows system. Rake aborted with &#8220;Command failed with status (127): [zip -r Module.zip Module...]&#8220;. What could be the problem? Status code 127 is commonly used to indicate &#8220;command &#8230; <a href="http://bengribaudo.com/blog/2012/01/25/1771/rake-package-task-fails-with-status-127-on-windows">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The other day, I tried running a <a href="http://rake.rubyforge.org/classes/Rake/PackageTask.html" target="_blank">Rake Package</a> task on a Windows system. Rake aborted with &#8220;<em>Command failed with status (127): [zip -r Module.zip Module...]</em>&#8220;. What could be the problem?<span id="more-1771"></span></p>
<p>Status code 127 is commonly used to indicate &#8220;command not found.&#8221; The error message&#8217;s bracketed portion indicates that Rake attempted to run an executable named &#8220;<em>zip</em>,&#8221; passing to it several arguments. By default, Windows systems do not include a command named zip. Hence, the error.</p>
<p>To fix this problem, configure Rake::PackageTask to use an alternative zip command by setting its <em>zip_command</em> property. In the example below, notice the inner quotes surrounding the path to the command. These were necessitated by the space in &#8220;Program Files.&#8221;</p>
<pre class="brush:ruby">Rake::PackageTask.new('Module', :noversion) do |p|
  p.need_zip = true
  p.zip_command = '"C:\Program Files\7-Zip\7z.exe" a -tzip'
  p.package_files.include(..)
end</pre>
<p>Rake::PackageTask also provides a <em>tar_command</em> property which can be used to override the command used to gzip and bzip2 archives.</p>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2012/01/25/1771/rake-package-task-fails-with-status-127-on-windows/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Storing Incomplete (Partial) Dates in SQL Databases</title>
		<link>http://bengribaudo.com/blog/2011/12/16/1721/storing-incomplete-partial-dates-in-sql-databases</link>
		<comments>http://bengribaudo.com/blog/2011/12/16/1721/storing-incomplete-partial-dates-in-sql-databases#comments</comments>
		<pubDate>Fri, 16 Dec 2011 20:23:32 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=1721</guid>
		<description><![CDATA[Complete (full) dates and unknown dates can easily be stored in a database table via a nullable date column. What about storing incomplete (partial) dates—where the month, day and/or year is unknown? How do we record July 10 (unknown year) &#8230; <a href="http://bengribaudo.com/blog/2011/12/16/1721/storing-incomplete-partial-dates-in-sql-databases">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Complete (full) dates and unknown dates can easily be stored in a database table via a nullable date column. What about storing incomplete (partial) dates—where the month, day and/or year is unknown? How do we record July 10 (unknown year) or June 2012 (unknown day)?<span id="more-1721"></span></p>
<p>MySQL <a href="http://dev.mysql.com/doc/refman/5.0/en/using-date.html" target="_blank">supports incomplete dates</a> out of the box. Simply insert zeros in place of the missing date part:</p>
<pre class="brush:sql">INSERT INTO TestTable (ID, IncompleteDate) VALUES
(NULL, '0000-07-10'), -- unknown year
(NULL, '2012-00-15'), -- unknown month
(NULL, '2012-06-00'); -- unknown day</pre>
<p>Microsoft SQL Server doesn&#8217;t support incomplete dates so zeroing out a missing date part won&#8217;t work. Let&#8217;s examine several ways to work around this limitation.</p>
<h2>Placeholder Year</h2>
<p>Suppose we&#8217;re storing birth dates. Let&#8217;s say we know that a day and month will always be provided but sometimes the year will be omitted. That is, sometimes we&#8217;ll need to store dates in the format of March 18 (unknown year).</p>
<p>To use the placeholder year approach, pick a year outside the range of expected year values to use as the unknown year placeholder. In order to accommodate the date February 29 (unknown year), the placeholder year must be a <a href="http://en.wikipedia.org/wiki/Leap_year#Algorithm" target="_blank">leap year</a>.  In the case of our birth date example, let&#8217;s choose year 1200 as the unknown placeholder. It&#8217;s well outside the range of birth dates used in a normal line of business application and is a leap year. To store March 18 (unknown year), we&#8217;ll insert &#8220;1200-03-18&#8243;.</p>
<p>With this approach, normal SQL <a href="http://msdn.microsoft.com/en-us/library/ms186724.aspx#DateandTimeFunctions" target="_blank">date functions</a> work. However, if computations involving the year are invoked, dates using the placeholder year must be filtered out.</p>
<pre class="brush:sql">-- Failed Attempt: Find individuals born before 1980.
-- (Problem: Records with unknown birth years will be included in the result set.)
SELECT *
FROM TestTable
WHERE YEAR(BirthDate) &lt; 1980

-- Successful Attempt: Find individuals born before 1980
SELECT *
FROM TestTable
WHERE YEAR(BirthDate) &gt; 1200 AND YEAR(BirthDate) &lt; 1980</pre>
<h2>Date Parts in Separate Columns</h2>
<p>To implement, create three columns: day, month, year. If a particular date part may be unknown, allow the associate column to store null values. To insert March 18 (unknown year), we execute:</p>
<pre class="brush:sql">INSERT INTO TestTable (BirthDay, BirthMonth, BirthYear) VALUES
(3, 18, NULL);</pre>
<p>This method eliminates the use of a placeholder year and allows for unknown days and months, benefits not offered by the<em> placeholder year</em> approach. Its principle downside? Loss of SQL Server&#8217;s built-in date functionality (<a href="http://msdn.microsoft.com/en-us/library/ms186724.aspx#DateandTimeFunctions" target="_blank">date functions</a>, <a href="http://msdn.microsoft.com/en-us/library/ms187928.aspx" target="_blank">conversion/cast operations</a> and date validation checking).</p>
<p>Date validation can be manually recreated using a somewhat complex set of <a href="http://msdn.microsoft.com/en-us/library/ms188258.aspx" target="_blank">CHECK constraints</a>. The loss of date functions may not be the end of the world. In fact, some operations may become easier. No longer is <em>MONTH(BirthDate)</em> necessary. Selecting <em>BirthMonth</em> now achieves the same effect.</p>
<h2>CLR User-Defined Type</h2>
<p>In addition to the benefits of the <em>date parts in separate columns</em> approach, a <a href="http://msdn.microsoft.com/en-us/library/ms131120.aspx" target="_blank">CLR user-defined type (UDT)</a> allows for a degree of cast/conversion operations and stores its data in a single column on the server. With this method, all functionality is packaged into a data type which can easily be reused server-wide. This data type can also be included in client-side programs, allowing those programs to locally <a href="http://msdn.microsoft.com/en-us/library/ms131066.aspx" target="_blank">work with retrieved data</a> using all the methods and properties defined by the custom data type.</p>
<p>The downside? Out of the methods discussed, this is the most complex to implement</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2011/12/16/1721/storing-incomplete-partial-dates-in-sql-databases/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Unit Testing &amp; Magento&#8217;s Autoloader</title>
		<link>http://bengribaudo.com/blog/2011/11/30/869/unit-testing-m-autoloader</link>
		<comments>http://bengribaudo.com/blog/2011/11/30/869/unit-testing-m-autoloader#comments</comments>
		<pubDate>Wed, 30 Nov 2011 21:29:37 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=869</guid>
		<description><![CDATA[If code written for Magento is executed outside of Magento—as occurs when running unit tests—Magento&#8217;s normal startup process (which registers its autoload functionality) is not run. Without the autoloader in place, the first time PHP encounters a request to initialize &#8230; <a href="http://bengribaudo.com/blog/2011/11/30/869/unit-testing-m-autoloader">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If code written for Magento is executed outside of Magento—as occurs when running unit tests—Magento&#8217;s normal startup process (which registers its autoload functionality) is not run. Without the <a href="http://php.net/manual/en/language.oop5.autoload.php" target="_blank">autoloader</a> in place, the first time PHP encounters a request to initialize a class which it doesn&#8217;t recognize, it will error out with a &#8220;class not found&#8221; error. Also, without Magento&#8217;s startup process running, PHP doesn&#8217;t know about the <em>Mage</em> family of singleton methods (e.g. <em>Mage::getModel(), Mage::helper()</em>) which are commonly used to create class instances.<span id="more-869"></span></p>
<h2>Solution</h2>
<p>Include/require (perhaps using <a href="http://php.net/manual/en/function.require-once.php" target="_blank">require_once</a>) app/Mage.php in the code you execute from outside of Magento. When Mage.php is included, the code in that file will register Magento&#8217;s autoloader with PHP. Also, Mage.php contains the method definitions for the <em>Mage</em> singleton methods.</p>
<p>Learn more about unit testing code written for Magento on <a href="http://www.magentocommerce.com/wiki/5_-_modules_and_development/phpunit_integration_with_magento" target="_blank">Magento&#8217;s wiki</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2011/11/30/869/unit-testing-m-autoloader/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Passing a Memo Field to SAGE Payment Soluations&#8217; Gateway API</title>
		<link>http://bengribaudo.com/blog/2011/10/31/1681/passing-a-memo-field-to-sage-payment-soluations-gateway-api</link>
		<comments>http://bengribaudo.com/blog/2011/10/31/1681/passing-a-memo-field-to-sage-payment-soluations-gateway-api#comments</comments>
		<pubDate>Mon, 31 Oct 2011 22:02:20 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Payment Processing]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=1681</guid>
		<description><![CDATA[In SAGE Payment Solutions&#8217; virtual terminal, transactions have a memo field. However, the gateway&#8217;s HTTPS Bankcard Specifications API documentation doesn&#8217;t mention a way to programmatically set this field. Using the HTTPS POST API, is there a way to pass in &#8230; <a href="http://bengribaudo.com/blog/2011/10/31/1681/passing-a-memo-field-to-sage-payment-soluations-gateway-api">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In SAGE Payment Solutions&#8217; virtual terminal, transactions have a memo field. However, the gateway&#8217;s <em>HTTPS Bankcard Specifications</em> API documentation doesn&#8217;t mention a way to programmatically set this field. Using the HTTPS POST API, is there a way to pass in memo text?<span id="more-1681"></span></p>
<p>Yes! In your authorization request, put the memo text in a field called<strong> T_memo</strong>.</p>
<p>Thanks to <a href="http://www.cornerstone.cc/" target="_blank">Cornerstone</a>, one of my client&#8217;s credit card processing vendor, for passing on this tip!</p>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2011/10/31/1681/passing-a-memo-field-to-sage-payment-soluations-gateway-api/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Show Insert File Instead of Record Audio Dialog  &#8211; FileMaker Pro Container Fields</title>
		<link>http://bengribaudo.com/blog/2011/09/13/1640/show-insert-file-instead-of-record-audio-dialog-fmp-container-fields</link>
		<comments>http://bengribaudo.com/blog/2011/09/13/1640/show-insert-file-instead-of-record-audio-dialog-fmp-container-fields#comments</comments>
		<pubDate>Tue, 13 Sep 2011 13:58:03 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Container Field]]></category>
		<category><![CDATA[FileMaker Pro]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=1640</guid>
		<description><![CDATA[Click on a container field in a FileMaker Pro form and you&#8217;ll be presented with a Record Audio dialog. To store a file or other non-audio content, you must right-click on the field and then choose Insert File (or Insert Image or &#8230; <a href="http://bengribaudo.com/blog/2011/09/13/1640/show-insert-file-instead-of-record-audio-dialog-fmp-container-fields">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Click on a container field in a FileMaker Pro form and you&#8217;ll be presented with a <em>Record Audio</em> dialog. To store a file or other non-audio content, you must right-click on the field and then choose <em>Insert File</em> (or <em>Insert Image</em> or <em>Insert Object</em>, etc.) from the pop-up menu. When a container field is primarily used to store non-audio content, the required right-clicking quickly gets old. How do you modify a container field&#8217;s behavior so that a left-click displays the <em>Insert File</em> dialog?<span id="more-1640"></span></p>
<h2>Foundation: The Script Comes First</h2>
<p><a href="http://bengribaudo.com/wp-content/uploads/2011/09/EditScriptShowInsertFileDialog.jpg" target="_blank"><img class="alignright size-medium wp-image-1662" title="Edit Script - &quot;Show Insert File Dialog&quot;" src="http://bengribaudo.com/wp-content/uploads/2011/09/EditScriptShowInsertFileDialog-300x219.jpg" alt="" width="300" height="219" /></a>Let&#8217;s start by creating a script that displays an <em>Insert File</em> dialog. This script should contain two steps: <em>Set Error Options [On]</em> followed by <em>Insert File [Table::FieldName] </em>(where <em>Table</em> is the name of the table containing the container field and <em>FieldName</em> is the name of the container field).</p>
<p>(<em>Set Error Options [On]</em> isn&#8217;t strictly necessary. However, if it&#8217;s left out and the user clicks cancels out of the <em>Insert File</em> dialog, a script error will be displayed.)</p>
<h2>The Container&#8217;s Button Setup</h2>
<p>Now, configure the container field&#8217;s button setup so that clicking on the field runs the script we just created. While editing the layout, right-click on the field, choose <em>Button Setup</em>, change the action to <em>Perform Script</em> then click <em>Specify</em> and select the script you created above. Switch from edit layout mode to view mode, then click on the container field. You should see an <em>Insert File</em> dialog. Excellent!</p>
<p>Ah&#8230;but there&#8217;s a catch. Normally, to export or delete the file stored in the container, you&#8217;d right-click on the field and choose the appropriate option from the pop-up menu. However, when we configured button setup, we overrode the field&#8217;s click behavior for <em>both</em> left- and right-clicks. Right-click on the field and <em>Insert File</em> appears instead of the pop-up menu. Unfortunately, FileMaker Pro doesn&#8217;t provide an easy way to limit our script so that it only processes left-clicks. If we want the script to handle clicks, it must handle <em>all</em> of them. What can we do about this?</p>
<h2>Separate Buttons</h2>
<p>It&#8217;s not pretty, but it works. Next to the container field, create two buttons: export and delete. Via button setup, associate each with a script that performs the appropriate action.</p>
<p><a href="http://bengribaudo.com/wp-content/uploads/2011/09/EditScriptExportFile.jpg" target="_blank"><img class="alignright size-medium wp-image-1663" title="Edit Script - &quot;Export File&quot;" src="http://bengribaudo.com/wp-content/uploads/2011/09/EditScriptExportFile-300x219.jpg" alt="" width="300" height="219" /></a>Export&#8217;s script contains two steps: <em>Set Error Capture [On]</em> and <em>Export Field Contents [Table::FieldName]</em>.</p>
<p><a href="http://bengribaudo.com/wp-content/uploads/2011/09/EditScriptDeleteFile.jpg" target="_blank"><img class="alignright size-medium wp-image-1664" title="Edit Script - &quot;Delete File&quot;" src="http://bengribaudo.com/wp-content/uploads/2011/09/EditScriptDeleteFile-300x219.jpg" alt="" width="300" height="219" /></a>Delete&#8217;s script uses an <em>If</em> statement to check if the container field is empty. If the field is not empty, the script calls <em>Set Field [Table::FieldName, ""]</em>.</p>
<p>Why the <em>If</em> statement? Without it, clicking the delete button on a brand-new, empty portal row sets the container field to a value which causes the portal row to be inserted into the table, even though it is empty. The <em>If</em> statement prevents this.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><a href="http://bengribaudo.com/wp-content/uploads/2011/09/ConditionalFormattingMakingButtonAppearDisabled.jpg" target="_blank"><img class="size-medium wp-image-1648 alignright" title="Conditional Formatting - Making Button Appear Disabled" src="http://bengribaudo.com/wp-content/uploads/2011/09/ConditionalFormattingMakingButtonAppearDisabled-300x258.jpg" alt="" width="300" height="258" /></a>To improve the user interface experience, conditional formatting can be used to make the two buttons appear disabled when the container field is empty.</p>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2011/09/13/1640/show-insert-file-instead-of-record-audio-dialog-fmp-container-fields/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SET FMTONLY ON Changes SQL Control-of-Flow Statement Processing</title>
		<link>http://bengribaudo.com/blog/2011/08/30/1570/set-fmtonly-on-changes-sql-control-of-flow-statement-processing</link>
		<comments>http://bengribaudo.com/blog/2011/08/30/1570/set-fmtonly-on-changes-sql-control-of-flow-statement-processing#comments</comments>
		<pubDate>Tue, 30 Aug 2011 20:38:27 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=1570</guid>
		<description><![CDATA[The other day, my friend Jonathan (of Camenisch Creative) surprised me by pointing out that SET FMTONLY ON changes the way Microsoft SQL Server processes control-of-flow statements (IF&#8230;ELSE&#8230;END, GOTO, RETURN, etc.) When SET FMTONLY is OFF (the default), SQL Server &#8230; <a href="http://bengribaudo.com/blog/2011/08/30/1570/set-fmtonly-on-changes-sql-control-of-flow-statement-processing">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The other day, my friend Jonathan (of <a href="http://camenischcreative.com/" target="_blank">Camenisch Creative</a>) surprised me by pointing out that SET FMTONLY ON <strong>changes the way Microsoft SQL Server processes control-of-flow statements</strong> (IF&#8230;ELSE&#8230;END, GOTO, RETURN, etc.)</p>
<p>When SET FMTONLY is OFF (the default), SQL Server processes control-of-flow statements normally. In the case of an IF statement, SQL Server determines which conditional expression evaluates to true and then executes the code associated with that expression. Turn FMTONLY to ON and SQL Server <strong>executes <em>every</em> conditional branch</strong>, even those associated with<strong> conditions evaluating to false</strong>!</p>
<p><span id="more-1570"></span></p>
<p>To illustrate, if SET FMTONLY is OFF, executing the following SQL returns one result set containing a column named <em>1 = 1</em>. With SET FMTONLY ON, the below SQL returns two result sets: one containing the already-mentioned <em>1 = 1</em> column and a second containing a column named <em>1 = 2</em>. When FMTONLY is ON, the code blocks associated with <em>both of these conditional expressions</em> are executed—even though one of the conditions evaluates to false!</p>
<pre class="brush:sql">IF 1 = 1
	SELECT '1 = 1' = 'Value'
ELSE IF 1 = 2
	-- Normally, this SELECT statement would not be executed because 1 does not equal 2.
	SELECT '1 = 2' = 'Value'
END</pre>
<p>Setting SET FMTONLY ON also changes the behavior of CONTINUE, RETURN and BREAK statements, TRY&#8230;CATCH blocks and WAITFOR statement as demonstrated by the following SQL:</p>
<pre class="brush:sql">SET FMTONLY ON;

DECLARE @counterContinue INT;
SET @counterContinue = 1;

WHILE (@counterContinue &lt; 10) BEGIN
	SET @counterContinue = @counterContinue + 1;
	CONTINUE;
	-- Normally, this next SELECT statement will never be executed because of the proceeding
	-- CONTINUE; however, SET FMTONLY ON causes it to be processed.
	SELECT 'Post Continue Table' = 'Value';
END

DECLARE @counterBreak INT;
SET @counterBreak = 1;

WHILE (@counterBreak &lt; 10) BEGIN
	SET @counterBreak = @counterBreak + 1;
	BREAK;
	-- If SET FMTONLY where OFF, this next SELECT statement wouldn't be run but
	-- because SET FMTONLY is ON, it will be executed.
	SELECT 'Post Break Table' = 'Value';
END

BEGIN TRY
	SELECT 'Try Table Column' = 'Value'
END TRY
-- Normally, this CATCH statement will only be executed if an error occurs in the TRY
-- statement block. With SET FMTONLY ON, the CATCH block will always be executed.
BEGIN CATCH
	SELECT 'Catch Table Column' = 'Value'
END CATCH

-- With SET FMTONLY ON, the no waiting occurs.
BEGIN
    WAITFOR DELAY '02:00';
    SELECT 'Wait' = 'Value'
END;

-- If SET FMTONLY is OFF, the code below this RETURN statement will never be executed.
-- When SET FMTONLY ON, the following SELECT statement is executed.
RETURN
AfterReturnLabel:
	SELECT 'After Return Label Table' = 'Value'</pre>
<h2>Why does FMTONLY ON cause this behavior change?</h2>
<p>Here&#8217;s my guess: SET FMTONLY ON is used to retrieve metadata describing the result set(s) that <em>could</em> be returned when the specified query is run (i.e. run with SET FMTONLY OFF). In order for SQL Server to provide metadata on <em>all</em> result sets that <em>could be</em> returned, SQL Server must process <em>all</em> branches of <em>all</em> control-of-flow statements.</p>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2011/08/30/1570/set-fmtonly-on-changes-sql-control-of-flow-statement-processing/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programmatically Setting a Magento Item&#8217;s Price When Adding It to Cart</title>
		<link>http://bengribaudo.com/blog/2011/07/29/1514/programmatically-setting-m-items-price-when-adding-to-cart</link>
		<comments>http://bengribaudo.com/blog/2011/07/29/1514/programmatically-setting-m-items-price-when-adding-to-cart#comments</comments>
		<pubDate>Fri, 29 Jul 2011 16:56:58 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Magento]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=1514</guid>
		<description><![CDATA[Using code, how would we give a Magento item a one-time special price then add that item to the shopping cart? The process is simple: Create an instance of the Magento product, give it a custom price by calling setSpecialPrice, &#8230; <a href="http://bengribaudo.com/blog/2011/07/29/1514/programmatically-setting-m-items-price-when-adding-to-cart">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Using code, how would we give a Magento item a one-time special price then add that item to the shopping cart?</p>
<p>The process is simple:</p>
<ul>
<li><strong>Create</strong> an instance of the Magento product,
<ul>
<li><strong>give</strong> it a custom price by calling setSpecialPrice,</li>
<li>then <strong>save</strong> the product instance (store must be running as the admin store).</li>
</ul>
</li>
<li><strong>Next</strong>, grab the Magento cart object (a singleton),
<ul>
<li><strong>add</strong> the product instance to the cart,</li>
<li>then <strong>save</strong> the cart.</li>
</ul>
</li>
</ul>
<p><span id="more-1514"></span>In order to save the product after giving it a special price, the store <em>must</em> be running as what Magento calls the &#8220;admin store&#8221; (confusing terminology—think of it as meaning &#8220;running in admin mode&#8221;). If save is called while the store is running in its default mode (in Magento-speak, &#8220;running as the distro store&#8221;), the following error will occur:</p>
<pre class="brush:xml">Warning: Invalid argument supplied for foreach()  in app\code\core\Mage\Eav\Model\Entity\Abstract.php on line 1068

#0 app\code\core\Mage\Eav\Model\Entity\Abstract.php(1068): mageCoreErrorHandler(2, 'Invalid argumen...', 'C:\Program File...', 1068, Array)
#1 app\code\core\Mage\Eav\Model\Entity\Abstract.php(1012): Mage_Eav_Model_Entity_Abstract-&gt;_collectSaveData(Object(Mage_Catalog_Model_Product))
#2 app\code\core\Mage\Core\Model\Abstract.php(318): Mage_Eav_Model_Entity_Abstract-&gt;save(Object(Mage_Catalog_Model_Product))
#3 app\code\local\BenGribaudo\MyModule\controllers\IndexController.php(26): Mage_Core_Model_Abstract-&gt;save()
#4 app\code\local\BenGribaudo\MyModule\controllers\IndexController.php(8): BenGribaudo_MyModule_IndexController-&gt;processAdd()
#5 app\code\core\Mage\Core\Controller\Varien\Action.php(418): BenGribaudo_MyModule_IndexController-&gt;indexAction()
#6 app\code\core\Mage\Core\Controller\Varien\Router\Standard.php(253): Mage_Core_Controller_Varien_Action-&gt;dispatch('index')
#7 app\code\core\Mage\Core\Controller\Varien\Front.php(176): Mage_Core_Controller_Varien_Router_Standard-&gt;match(Object(Mage_Core_Controller_Request_Http))
#8 app\code\core\Mage\Core\Model\App.php(340): Mage_Core_Controller_Varien_Front-&gt;dispatch()
#9 app\Mage.php(627): Mage_Core_Model_App-&gt;run(Array)
#10 index.php(80): Mage::run('', 'store')
#11 {main}</pre>
<p>After saving the product instance, be sure to switch the store back to normal (a.k.a. distro) mode before adding the product to the cart. Otherwise, the item just added to the cart will disappear out of the cart. (Most articles I&#8217;ve seen on this topic leave out this important step.)</p>
<h2>Code Example</h2>
<pre class="brush:php">$product = Mage::getModel('catalog/product');
$product-&gt;load($productId);
$product-&gt;setSpecialPrice($price);
Mage::app()-&gt;setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$product-&gt;save();
Mage::app()-&gt;setCurrentStore(Mage_Core_Model_App::DISTRO_STORE_ID);

$cart = Mage::getSingleton('checkout/cart');
$cart-&gt;addProduct($product, array('qty' =&gt; $quantity));
$cart-&gt;save();</pre>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2011/07/29/1514/programmatically-setting-m-items-price-when-adding-to-cart/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Can you force .Net garbage collection?</title>
		<link>http://bengribaudo.com/blog/2011/06/04/1405/can-net-garbage-collection-be-forced</link>
		<comments>http://bengribaudo.com/blog/2011/06/04/1405/can-net-garbage-collection-be-forced#comments</comments>
		<pubDate>Sat, 04 Jun 2011 23:50:21 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Garbage Collection]]></category>

		<guid isPermaLink="false">http://bengribaudo.com/?p=1405</guid>
		<description><![CDATA[Confusion exists on whether .Net&#8217;s GC.Collect() simply suggests or actually forces garbage collection (GC). Thankfully, developers don&#8217;t usually need to worry about such mundane details. However, in unusual circumstances—like WeakReference testing (which may rely on predictable, guaranteed destruction of unneeded &#8230; <a href="http://bengribaudo.com/blog/2011/06/04/1405/can-net-garbage-collection-be-forced">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Confusion exists on whether .Net&#8217;s <a href="http://msdn.microsoft.com/en-us/library/y46kxc5e%28v=VS.80%29.aspx" target="_blank">GC.Collect()</a> simply <em>suggests </em>or actually <em>forces </em>garbage collection (GC). Thankfully, developers don&#8217;t usually need to worry about such mundane details. However, in unusual circumstances—like <a href="http://msdn.microsoft.com/en-us/library/system.weakreference.aspx" target="_blank">WeakReference</a> testing (which may rely on predictable, guaranteed destruction of unneeded objects)—particulars like this become vitally important.<span id="more-1405"></span></p>
<h2>Can the garbage collection <em>process </em>be forced to run?</h2>
<p>MSDN says that <a href="http://msdn.microsoft.com/en-us/library/y46kxc5e%28v=VS.80%29.aspx" target="_blank">GC.Collect()</a> &#8220;forces garbage collection.&#8221; This is as clear as can be. Calling GC.Collect() doesn&#8217;t request or suggest garbage collection—when it is called, collection always occurs.</p>
<h2>When collection is induced, will <em>all </em>eligible objects be destroyed?</h2>
<p>Calling GC.Collect() destroys all non-finalizable collection-eligible objects. Finalizable object destruction involves two additional steps (assuming that no object resurrection occurs): after the initial GC.Collect() call, wait for the finalizers to run, then call GC.Collect() a second time. In both cases, the collector will not mysteriously skip over eligible objects. <em>Any </em>object which qualifies for destruction <em>will </em>be discarded.</p>
<p>Destroying an object is different from <em>freeing the memory</em> used by the object. If a WeakReference points to an object which is garbage collected, the WeakReference&#8217;s <a href="http://msdn.microsoft.com/en-us/library/system.weakreference.isalive.aspx" target="_blank">IsAlive</a> property will equal false—the object has been destroyed. However, sometimes it is inefficient for the garbage collector to free up the memory used by the destroyed object. <a href="http://msdn.microsoft.com/en-us/library/y46kxc5e%28v=VS.80%29.aspx" target="_blank">GC.Collect()</a>&#8216;s documentation alludes to this with the word &#8220;try&#8221; when it says &#8220;Use this method to <em>try </em>to reclaim all memory that is inaccessible&#8221; (emphasis mine). The object has been destroyed even if the memory it used has not been released.</p>
<h2>Closing Thoughts</h2>
<p>Other programming languages&#8217; garbage collection implementations may operate differently. It&#8217;s important not to confuse the specifics of how they work with how .Net works.</p>
<p>For details on how .Net determines when an object is eligible for garbage collection, read Jeffrey Richter&#8217;s MSDN Magazine article <em><a href="http://msdn.microsoft.com/en-us/magazine/bb985010.aspx" target="_blank">Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework</a></em>.</p>
<p>Thanks goes to <a href="http://blogs.msdn.com/b/maoni/" target="_blank">Maoni Stephens</a> for helping me understand several pertinent garbage collection particulars.</p>
]]></content:encoded>
			<wfw:commentRss>http://bengribaudo.com/blog/2011/06/04/1405/can-net-garbage-collection-be-forced/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

