Printing a subarray in an array in smarty (foreach) - foreach

I'm trying to print a subarray in an array with the smarty template engine. Say I have an array structure like this:
Array
(
[0] => Array
(
[directory] => One Day As A Lion - 2011-03-01/
[source_notes] => iRiver
[recording_type] => Audience
[type] => Audio
[source_type] => MP3
[fileList] => Array
(
[0] => 09 One Day As A Lion.mp3
[1] => 01 Intro.mp3
[2] => 05 Ocean View.mp3
[3] => 04 Swashbuckler.mp3
[4] => One Day As A Lion - 2011-03-01 - Prince Bandroom, Melbourne, Australia.jpg
[5] => 10 Peart Plus.mp3
[6] => 06 Rockers.mp3
[7] => 03 Last Letter.mp3
[8] => 07 Swampy.mp3
[9] => 02 If You Fear Dying.mp3
[10] => 08 Wild International.mp3
)
)
)
How exactly would I get the array containing the filenames to print in smarty? Currently I have a foreach loop in smarty that looks like:
{foreach $sources as $sourceInfo}
{strip}
Recording Type: {$sourceInfo.type} : {$sourceInfo.recording_type}<br>
Source : {$sourceInfo.source_notes}<br>
{/strip}
{/foreach}
And I'm not sure how to implement a second foreach loop. Does anyone have any suggestions? I'm a little confused with the documentation since there seems to be two methods of nested foreach loops, one of which seems to be deprecated. Is a foreach loop the best way to do it, or is there another recommended way in smarty? Any feedback would be much appreciated. Thanks!

Simply add another foreach:
{foreach from=$sources item=sourceInfo}
{strip}
Recording Type: {$sourceInfo.type} : {$sourceInfo.recording_type}<br>
Source : {$sourceInfo.source_notes}<br>
Files: {foreach from=$sourceInfo.fileList item=file}{$file}, {foreachelse}<i>no files</i>{/foreach}
{/strip}
{/foreach}

Related

'last' method not returning last item in array in RSpec test - Rails4 Ruby 2.1.2

Was working on an RSpec test that copies #protocol to #dest and saw this:
[26] pry(#<RSpec::ExampleGroups::ProtocolsController::ProtocolCopy>)> #protocol.step_items.count
=> 3
[27] pry(#<RSpec::ExampleGroups::ProtocolsController::ProtocolCopy>)> assigns(:dest).step_items.count
=> 3
[28] pry(#<RSpec::ExampleGroups::ProtocolsController::ProtocolCopy>)> #protocol.step_items[2].note
=> "note3"
[29] pry(#<RSpec::ExampleGroups::ProtocolsController::ProtocolCopy>)> assigns(:dest).step_items[2].note
=> "note3"
[30] displayed an instance variable. Removed for berevity
[31] pry(#<RSpec::ExampleGroups::ProtocolsController::ProtocolCopy>)> #protocol.step_items.last.note
=> "note3"
[32] pry(#<RSpec::ExampleGroups::ProtocolsController::ProtocolCopy>)> assigns(:dest).step_items.last.note
=> "note2"
[33] pry(#<RSpec::ExampleGroups::ProtocolsController::ProtocolCopy>)> assigns(:dest).step_items.last.last?
=> false
[34] pry(#<RSpec::ExampleGroups::ProtocolsController::ProtocolCopy>)>
pastebin of the pry session may be easier to read here.
My gemfile is here.
Seems assigns(:dest).step_items.last is returning the second-to-last item in the array.
Result is reproducible. Looks like a bug to me. Is this some odd RSpec side effect? Is this somehow related to my use of acts_as_list? Either way, it seems like a wrong result for 'last'.

Return upcoming YouTube API V3 video schedule date?

I'm looking to return the schedule date for a stream in YouTube.
Example of scheduled streams:
YT Link: https://www.youtube.com/channel/UCP7jMXSY2xbc3KCAE0MHQ-A
This is my code to pull this data out using the YouTube v3 API:
$videos = $this->yt->searchAdvanced(array(
'q' => '',
'part' => 'snippet',
'channelId' => $this->channel_id,
'eventType' => $event_type, // Upcoming
'type' => 'video',
'order' => 'date',
'maxResults' => $max,
'key' => YOUTUBE_API_KEY
));
Here is the object that is returned from this:
If I use my function to get video info this is all the information I can get. This is using parts:
id, snippet, contentDetails, player, statistics, status
: Where is the scheduled date? :
stdClass Object
(
[kind] => youtube#video
[etag] => "q5k97EMVGxODeKcDgp8gnMu79wM/KAZsrzeX5ImiUQpLbwhPR7lo9mA"
[id] => qUAmTYHEyM8
[snippet] => stdClass Object
(
[publishedAt] => 2016-03-03T06:48:50.000Z
[channelId] => UCP7jMXSY2xbc3KCAE0MHQ-A
[title] => Match 3 - Google DeepMind Challenge Match: Lee Sedol vs AlphaGo
[description] => Watch DeepMind's program AlphaGo take on the legendary Lee Sedol (9-dan pro), the top Go player of the past decade, in a $1M 5-game challenge match in Seoul. This is the livestream for Match 3 to be played on: 12th March 13:00 KST (local), 04:00 GMT; note for US viewers this is the day before on: 11th March 20:00 PT, 23:00 ET.
In October 2015, AlphaGo became the first computer program ever to beat a professional Go player by winning 5-0 against the reigning 3-times European Champion Fan Hui (2-dan pro). That work was featured in a front cover article in the science journal Nature in January 2016.
Match commentary by Michael Redmond (9-dan pro) and Chris Garlock.
[thumbnails] => stdClass Object
(
[default] => stdClass Object
(
[url] => https://i.ytimg.com/vi/qUAmTYHEyM8/default_live.jpg
[width] => 120
[height] => 90
)
[medium] => stdClass Object
(
[url] => https://i.ytimg.com/vi/qUAmTYHEyM8/mqdefault_live.jpg
[width] => 320
[height] => 180
)
[high] => stdClass Object
(
[url] => https://i.ytimg.com/vi/qUAmTYHEyM8/hqdefault_live.jpg
[width] => 480
[height] => 360
)
[standard] => stdClass Object
(
[url] => https://i.ytimg.com/vi/qUAmTYHEyM8/sddefault_live.jpg
[width] => 640
[height] => 480
)
[maxres] => stdClass Object
(
[url] => https://i.ytimg.com/vi/qUAmTYHEyM8/maxresdefault_live.jpg
[width] => 1280
[height] => 720
)
)
[channelTitle] => DeepMind
[categoryId] => 28
[liveBroadcastContent] => upcoming
[localized] => stdClass Object
(
[title] => Match 3 - Google DeepMind Challenge Match: Lee Sedol vs AlphaGo
[description] => Watch DeepMind's program AlphaGo take on the legendary Lee Sedol (9-dan pro), the top Go player of the past decade, in a $1M 5-game challenge match in Seoul. This is the livestream for Match 3 to be played on: 12th March 13:00 KST (local), 04:00 GMT; note for US viewers this is the day before on: 11th March 20:00 PT, 23:00 ET.
In October 2015, AlphaGo became the first computer program ever to beat a professional Go player by winning 5-0 against the reigning 3-times European Champion Fan Hui (2-dan pro). That work was featured in a front cover article in the science journal Nature in January 2016.
Match commentary by Michael Redmond (9-dan pro) and Chris Garlock.
)
)
[contentDetails] => stdClass Object
(
[duration] => PT0S
[dimension] => 2d
[definition] => sd
[caption] => false
[licensedContent] => 1
)
[status] => stdClass Object
(
[uploadStatus] => uploaded
[privacyStatus] => public
[license] => youtube
[embeddable] => 1
[publicStatsViewable] => 1
)
[statistics] => stdClass Object
(
[viewCount] => 41
[likeCount] => 1
[dislikeCount] => 0
[favoriteCount] => 0
[commentCount] => 0
)
[player] => stdClass Object
(
[embedHtml] =>
)
)
Note that the published date I highlighted is NOT the schedule date.
As you can see there is no scheduled date. Do I need to pass more data to 'part'? Their API suggests there's no more data that can be pulled back too.
https://developers.google.com/youtube/v3/docs/search/list#request
Thanks
Okay I worked it out.
Simply add liveStreamingDetails to the part parameter.
I was trying to achieve this through search.list. Instead use the videos.list with liveStreamingDetails to get the schedule date as search.list doesn't support liveStreamingDetails.
Cheers
The YouTube Live Streaming API's list documentation has a relevant example:
list (by broadcast status) ...retrieve information about all, active, completed, or upcoming live broadcasts. Note that the broadcastStatus parameter is also set to all to ensure that all matching broadcasts are included in the response.
GET https://www.googleapis.com/youtube/v3/liveBroadcasts?part=snippet%2CcontentDetails%2Cstatus&broadcastStatus=active&broadcastType=all&key=[YOUR_API_KEY] HTTP/1.1
Authorization: Bearer [YOUR_ACCESS_TOKEN]
Accept: application/json
The start time can be found in the part=liveStreamingDetails, which will contain scheduledStartTime in ISO format, and activeLiveChatId.

Displaying MongoDB results in chartkick using ruby on rails

I have this output from a query in MongoDB using Ruby :
irb(main):087:0> data = col.find({}, :fields => ["result", "time"])
=> <Mongo::Cursor:0x14768b8 namespace='spark.light' #selector={} #cursor_id=>
irb(main):090:0> data.first
=> {"_id"=>BSON::ObjectId('537d961197c20960ad000001'), "result"=>2177, "time"=>2014-05-22 06:15:45 UTC}
Now I want to give this data to chartkick running on Ruby on Rails to draw a linechart
.The input shall looks like this :
"2014-05-22 06:15:45 UTC" => "2177"
Is there any clean way to do that ?
This would transform records into a hash of time => result:
Hash[data.map do |item|
[item['time'], item['result']]
end]
# => { 2014-05-22 06:15:45 UTC => 2177, 2014-05-22 06:20:00 UTC => 1000 }
Use Hash#values_at with Hash::[] method :
Hash[data.first.values_at('time', 'result')]

FedEx 556 - No valid services available. when there should be

Hi I'm trying to use the wsdl api to get shipping cost calculated for my website.
I'm using opencart and this module (http://www.opencart.com/index.php?route=extension/extension/info&extension_id=2055&filter_search=fedex&sort=e.date_modified&order=DESC).
On checkout I'm getting this error:
WARNING::556::There are no valid services available.
But I tried the same from and to address on the calculator on the fedex website and it gives me two services: International Priority and International Economy
This is the debug data I have:
Array
(
[WebAuthenticationDetail] => Array
(
[UserCredential] => Array
(
[Key] => REDACTED
[Password] => REDACTED
)
)
[ClientDetail] => Array
(
[AccountNumber] => REDACTED
[MeterNumber] => REDACTED
)
[TransactionDetail] => Array
(
[CustomerTransactionId] => *** Rate Request v9 using PHP ***
)
[Version] => Array
(
[ServiceId] => crs
[Major] => 9
[Intermediate] => 0
[Minor] => 0
)
[ReturnTransitAndCommit] => 1
[RequestedShipment] => Array
(
[DropoffType] => REQUEST_COURIER
[ShipTimestamp] => 2011-09-28T09:02:01+00:00
[PackagingType] => YOUR_PACKAGING
[TotalInsuredValue] => Array
(
[Amount] => 2000
[Currency] => EUR
)
[Shipper] => Array
(
[Address] => Array
(
[StreetLines] => Array
(
[0] =>
[1] =>
)
[City] => Ronchis
[StateOrProvinceCode] =>
[PostalCode] => 33050
[CountryCode] => IT
[Residential] => 1
)
)
[Recipient] => Array
(
[Address] => Array
(
[StreetLines] => Array
(
[0] =>
[1] =>
)
[City] => villach
[StateOrProvinceCode] =>
[PostalCode] => 9500
[CountryCode] => AT
[Residential] => 1
)
)
[ShippingChargesPayment] => Array
(
[PaymentType] => SENDER
[Payor] => Array
(
[AccountNumber] => 263150082
[CountryCode] => IT
)
)
[RateRequestTypes] => LIST
[PackageCount] => 1
[PackageDetailSpecified] => 1
[PackageDetail] => INDIVIDUAL_PACKAGES
[RequestedPackageLineItems] => Array
(
[0] => Array
(
[Weight] => Array
(
[Value] => 34
[Units] => KG
)
[Dimensions] => Array
(
[Length] => 48
[Width] => 53
[Height] => 122
[Units] => CM
)
)
)
)
)
----------
-- NUSOAP -- Array
(
[HighestSeverity] => WARNING
[Notifications] => Array
(
[Severity] => WARNING
[Source] => crs
[Code] => 556
[Message] => There are no valid services available.
[LocalizedMessage] => There are no valid services available.
)
[TransactionDetail] => Array
(
[CustomerTransactionId] => *** Rate Request v9 using PHP ***
)
[Version] => Array
(
[ServiceId] => crs
[Major] => 9
[Intermediate] => 0
[Minor] => 0
)
)
What should I do?
I just ran into this error, and it turned out that the issue was an invalid postal code. Double check that you are specifying the "Shipper" information correctly.
Also, if that doesn't work give the FedEx customer support phone number a try. We would not have figured this issue out without their help.
I was also having this issue .. but with Joomla, Virtuemart. Because the FedEx server is the same so may be my solution could help somebody else too..
Here are the main things what I fixed to fix this issue.
Product's Weight should be less than the limit if you've set any as Maximum Weight.
If you are using any packaging has more weight than FedEx's provided box i.e. 25KG BOX or 10KG box, then always use "Your Own packaging"
it's true, do keep an eye on ZIP===States (i was testing and put wrong state with different zip) And this ZIP should be added in "Shop's Address" because this is considered as FROM and the destination address as well.
Do note if products have added weights. LWH (Length, Width, Height).
Mine issue resolved after weeks of trouble! I wish somebody else could also resolve this issue if facing.
I was facing following error
"10 kg packaging box is **only** Available at FedEx World Service CenterĀ® locations!"
which was a big help to resolve the limitation i've set.
This issue happen when one of the bellow cases.
Country given is not associated with FedEx account.
Origin address is not real, Especially the post code.
The given packagingType is available in your country.
You need to provide a ServiceType. One of these:
EUROPE_FIRST_INTERNATIONAL_PRIORITY
FEDEX_1_DAY_FREIGHT
FEDEX_2_DAY
FEDEX_2_DAY_AM
FEDEX_2_DAY_FREIGHT
FEDEX_3_DAY_FREIGHT
FEDEX_EXPRESS_SAVER
FEDEX_FIRST_FREIGHT
FEDEX_FREIGHT_ECONOMY
FEDEX_FREIGHT_PRIORITY
FEDEX_GROUND
FIRST_OVERNIGHT
GROUND_HOME_DELIVERY
INTERNATIONAL_ECONOMY
INTERNATIONAL_ECONOMY_FREIGHT
INTERNATIONAL_FIRST
INTERNATIONAL_PRIORITY
INTERNATIONAL_PRIORITY_FREIGHT
PRIORITY_OVERNIGHT
SMART_POST
STANDARD_OVERNIGHT
Use it in the same level as the DropoffType
Make sure that you have the Zip Code set to required.
You can do that in System -> Localization -> Countries.
It is not required by default in opencart, and the fedex shipping system will not work without it.
This issue can also be caused by requesting insurance in a country that doesn't support it, such as Canada.
I also ran into this problem and the solution was trimming extra spaces from the end of the address, city & postal code. After that, all was well again.
I don't know why FedEx's API all of a sudden stopped accepting the extra spaces, but who knows...
In my case, this was caused by trying to ship internationally from the US to Italy, and having specified a SignatureOptionDetail of NO_SIGNATURE_REQUIRED. Changing this to SERVICE_DEFAULT fixed it.

Is there equivalent for PHP's print_r in Ruby / Rails?

In PHP you can do:
print_r($var) or vardump($var)
which prints "human-readible" information about variable.
Is there equivalent functions / helpers for those in Ruby / Rails ?
In Rails templates you can do
<%= debug an_object %>
and it will do nice HTML PRE output.
Try using pp.
You will need to require it in scripts (or in irb if your .irbc doesn't already do this):
require 'pp'
Then you can 'PrettyPrint' an object thus:
pp object
Instead of requiring 'pp' and using pp, you can simply do
p object
Tested example
require 'pp'
class A
def initialize
#a = 'somevar'
#b = [1,2,3]
#c = {'var' => 'val'}
end
end
a = A.new
pp a # Gives -> #<A:0x2c6d048 #a="somevar", #b=[1, 2, 3], #c={"var"=>"val"}>
p a # Gives -> #<A:0x2c6d048 #a="somevar", #b=[1, 2, 3], #c={"var"=>"val"}>. No need to require 'pp'
There's the method inspect which helps. Sometimes calling the to_s method on an object will help (to_s returns a string representation of the object). You can also query methods, local_variables, class_variables, instance_variables, constants and global_variables.
p ['Hello',"G'day",'Bonjour','Hola'].inspect
# >> "[\"Hello\", \"G'day\", \"Bonjour\", \"Hola\"]"
p ['Hello',"G'day",'Bonjour','Hola'].to_s
# >> "HelloG'dayBonjourHola"
p Array.new.methods
# >> ["select", "[]=", "inspect", "compact"...]
monkey = 'baboon'
p local_variables
# >> ["monkey"]
class Something
def initialize
#x, #y = 'foo', 'bar'
##class_variable = 'gorilla'
end
end
p Something.class_variables
# >> ["##class_variable"]
s = Something.new
p s.instance_variables
# >> ["#x", "#y"]
p IO.constants
# >> ["TRUNC", "SEEK_END", "LOCK_SH"...]
p global_variables
# >> ["$-d", "$\"", "$$", "$<", "$_", "$-K"...]
I know this is an old post, but it is the first thing that Google pops up when searching for "Ruby equivalent of PHP print_r". I'm using Ruby in the command line mode, and there's really not a very good equivalent. "pp" is ok for fairly simple structures, but as soon as you start nesting hashes in arrays in hashes in more arrays, it turns into a jumble pretty fast. Since I haven't found a good emulation of print_r, I wrote one myself. It's good enough for my purposes, not overly complicated and I thought I'd share it to save other people some headache. Compare the output with the real PHP print_r
def print_r(inHash, *indent)
#indent = indent.join
if (inHash.class.to_s == "Hash") then
print "Hash\n#{#indent}(\n"
inHash.each { |key, value|
if (value.class.to_s =~ /Hash/) || (value.class.to_s =~ /Array/) then
print "#{#indent} [#{key}] => "
self.print_r(value, "#{#indent} ")
else
puts "#{#indent} [#{key}] => #{value}"
end
}
puts "#{#indent})\n"
elsif (inHash.class.to_s == "Array") then
print "Array\n#{#indent}(\n"
inHash.each_with_index { |value,index|
if (value.class.to_s == "Hash") || (value.class.to_s == "Array") then
print "#{#indent} [#{index}] => "
self.print_r(value, "#{#indent} ")
else
puts "#{#indent} [#{index}] => #{value}"
end
}
puts "#{#indent})\n"
end
# Pop last indent off
8.times {#indent.chop!}
end
Here's an example (made messy on purpose to show why the PHP print_r is so nice):
carTools = [ "Socket Set", "Combination Wrenches", "Oil Filter puller", "Brake Compressor" ]
houseTools =[ "Circular Saw", "Miter Saw", "Drill" ]
garageItems = Hash["Car1" => "Ford Mustang", "Car2" => "Honda Civic", "Bike1" => "IronHorse"]
garageItems["Tools"] = Hash["Car Tools" => carTools, "House Tools" => houseTools]
constructionSupplies = Hash["Plywood" => ["3/4\" T&G Plywood Sheets", "1/2\" Plywood Sheets"],
"Boards" => ["2x4s", "2x6s", "Engineered I-Joists"],
"Drywall" => ["4x8 1/2\" Sheetrock", "Mesh tape", "Paper tape", "Joint compount"]]
carParts = Hash["Mustang" => ["Clutch", "Transmission", "3.55 Ring & Pinion Gears", "Differential", "30# Injectors", "Pro-M 77mm MAF"]]
garageItems["Supplies"] = ["Oil", "WD40", constructionSupplies, carParts, "Brake Fluid"]
print_r(garageItems)
Output of print_r (actually comprehensible by a human):
Hash
(
[Car1] => Ford Mustang
[Car2] => Honda Civic
[Bike1] => IronHorse
[Tools] => Hash
(
[Car Tools] => Array
(
[0] => Socket Set
[1] => Combination Wrenches
[2] => Oil Filter puller
[3] => Brake Compressor
)
[House Tools] => Array
(
[0] => Circular Saw
[1] => Miter Saw
[2] => Drill
)
)
[Supplies] => Array
(
[0] => Oil
[1] => WD40
[2] => Hash
(
[Plywood] => Array
(
[0] => 3/4" T&G Plywood Sheets
[1] => 1/2" Plywood Sheets
)
[Boards] => Array
(
[0] => 2x4s
[1] => 2x6s
[2] => Engineered I-Joists
)
[Drywall] => Array
(
[0] => 4x8 1/2" Sheetrock
[1] => Mesh tape
[2] => Paper tape
[3] => Joint compount
)
)
[3] => Hash
(
[Mustang] => Array
(
[0] => Clutch
[1] => Transmission
[2] => 3.55 Ring & Pinion Gears
[3] => Differential
[4] => 30# Injectors
[5] => Pro-M 77mm MAF
)
)
[4] => Brake Fluid
)
)
Check out the guide for debugging rails:
http://guides.rubyonrails.com/debugging_rails_applications.html
hints:
script/console is great to try stuff in the context of your app
script/server --debugger to start the server with a debugger turned on, you can then use 'debug' in your code to break into an interactive shell
One approach I lean on a lot is this:
logger.debug "OBJECT: #{an_object.to_yaml}"
Easy to read, although it can get a little unwieldy for large objects.
Guess I'm a little late to this, but what about logger.info [debug|warning]? Use this from Controllers and Models. It will show up in your log files (development.log when in dev mode); and the above mentioned <%= debug("str: " + str) %> for views.
These aren't exact answers to your questions but you can also use script/console to load your rails app in to an interactive session.
Lastly, you can place debugger in a line of your rails application and the browser will "hang" when your app executes this line and you'll be able to be in a debug session from the exact line your placed your debugger in the source code.

Resources