I would like to name the methods with an array like this
class MyClass {
private $_array = array();
public function __construct($array) {
$this->_array = $array; //this works!
}
//now, what i'm trying to do is:
foreach ($this->_array AS $methodName) {
public function $methodName.() {
//do something
}
}
}
What's the right way to do this?
when you working with classes and want something like dynamic methods - i think the magic method __call is the best way.
you can make it very easily:
class MyClass {
private $_array = array();
public function __construct($array) {
$this->_array = $array; //this works!
}
public function __call($method, $args) {
if(in_array($method, $this->_array)){
print "Method $method called\n";
//or you can make like this: return call_user_func_array($method, $args);
}
}
}
$obj = new MyClass(array("one","two"));
$obj->two(); // OUTPUT: Method two called
Related
I am having issue with the route and controller.
The error code consist of sql column not found which is looking for column id from items table. Which im quite curious due to the differences with my migration.
CartController.php
namespace App\Http\Controllers;
use App\Cart;
use App\CartItem;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class CartController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function addItem ($itemNo){
$cart = Cart::where('user_id',Auth::user()->id)->first();
if(!$cart){
$cart = new Cart();
$cart->user_id=Auth::user()->id;
$cart->save();
}
$cartItem = new Cartitem();
$cartItem->itemNo=$itemNo;
$cartItem->cart_id= $cart->id;
$cartItem->save();
return redirect('/cart');
}
public function showCart(){
$cart = Cart::where('user_id',Auth::user()->id)->first();
if(!$cart){
$cart = new Cart();
$cart->user_id=Auth::user()->id;
$cart->save();
}
$items = $cart->cartItems;
$total=0;
foreach($items as $item){
$total+=$item->product->price;
}
return view('cart.view',['items'=>$items,'total'=>$total]);
}
public function removeItem($id){
CartItem::destroy($id);
return redirect('/cart');
}
}
ItemController.php
<?php
namespace App\Http\Controllers;
use App\Item;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
class ItemController extends Controller
{
public function index(){
$items = item::all();
return view('admin.items',['items' => $items]);
}
public function destroy($itemNo){
item::destroy($itemNo);
return redirect('/admin/items');
}
public function newItem(){
return view('admin.new');
}
public function add() {
$file = Request::file('file');
$extension = $file->getClientOriginalExtension();
Storage::disk('local')->put($file->getFilename().'.'.$extension, File::get($file));
$entry = new \App\File();
$entry->mime = $file->getClientMimeType();
$entry->original_filename = $file->getClientOriginalName();
$entry->filename = $file->getFilename().'.'.$extension;
$entry->save();
$Item = new Item();
$Item->file_id=$entry->id;
$Item->itemName =Request::input('name');
$Item->itemDescription =Request::input('description');
$Item->price =Request::input('price');
$Item->imageurl =Request::input('imageurl');
$Item->save();
return redirect('admin/items');
}
}
Im making an inventory and Im adding stacks but ive hit an issue
below is what I want compared to what works
I just want to find the index of the object I pass through
myArray[0] = [item:object,StackAmmount:int]
var myArray:Array = new Array();
myArray[0] = ["name1",1];
myArray[1] = ["name2",1];
myArray[2] = ["name3",1];
trace("Name" , myArray[0][0]);
//traces "name1"
trace("Stack" , myArray[0][1]);
//traces "1"
trace("Index of Object" , myArray.indexOf("name2"));
//traces -1
// Not Working (NOT FOUND)
//How can I find the index of "item1" or "item2" in the above example
var myOtherArray:Array = new Array();
myOtherArray[0] = "name1";
myOtherArray[1] = "name2";
myOtherArray[2] = "name3";
trace("Name" , myOtherArray[0]);
//traces "name1"
trace("Index of Object" , myOtherArray.indexOf("name2"));
//traces 1
//Working
perhaps there is a better way of dealing with stacks?
Paste Bin Link: http://pastebin.com/CQZWFmST
I would use a custom class, therefore a 1D vector would be enough. The class would contain the name of the item, and the stack. You could subclass this class to override the maxStack variable of the item, and then the searches would be easier aswell, you could just iterate through the vector and check the name.
public class InventoryItem
{
protected var _name:String;
protected var _stack:int;
protected var _maxStack:int;
public function InventoryItem():void {
}
public function get name():String {
return _name;
}
public function get stack():int {
return _stack;
}
public function set stack(value:int):void {
_stack = value;
}
public function get maxStack():int {
return _maxStack;
}
}
...
public class InventoryWeapon extends InventoryItem
{
public function InventoryWeapon(__name:String, startStack:int) {
_maxStack = 64;
_name = __name;
_stack = startStack;
}
}
I'm trying to write a method for a class Queue that inverts the whole Queue. After running the program, it gives the follow problem:
Cannot use object of type Queue as array on line echo($i.".
".$this->kolejka[$i-1]."<br>");
Apparently when he is trying to use printOut method again on the inverted Queue. Please help!
Please don't laugh (too hard) as I tried many things to make this work and I'm lost.
Here is the whole code:
<?php
class Queue
{
private $Queue = array(); //Init
public function clear() //Clears the Queue
{
$this->Queue = array();
}
public function isMember($item) //Returns True if element is in the Queue
{
foreach($this->Queue as $x)
{
if($item === $x)
{
return true;
}
}
return false;
}
public function remove() //Removes first element
{
return array_shift($this->Queue);
}
public function add($item) //Adds element to the end
{
$this->Queue[] = $item;
}
public function first() //Returns the first element
{
return current($this->Queue);
}
public function printOut() //Writes down in order all the elements
{
for($i=1;$i < count($this->Queue)+1;$i++)
{
echo($i.". ".$this->Queue[$i-1]."<br>");
}
}
public function length() //Returnts length
{
return count($this->Queue);
}
public function invert() //Reverts the Queue
{
$newQueue = new Queue();
for ($i = $this->length() - 1;$i>=0;$i--)
{
$newQueue->add($this->first());
$this->remove();
}
$this->Queue = $newQueue;
}
}
$kolej = new Queue();
$kolej->add("Apple");
$kolej->add("Orange");
$kolej->add("Banana");
$kolej->add("Mandarin");
$kolej->add("Raspberry");
echo $kolej->first()."<br>";
$kolej->remove();
echo $kolej->first()."<br>";
echo $kolej->isMember("Apple")."<br>";
echo $kolej->isMember("Orange")."<br>";
$kolej->printOut();
echo "Currently Queue is of length ".$kolej->length()."<br>";
$kolej->invert();
$kolej->printOut();
?>
your invert() function is doing the wrong thing. $this->Queue is supposed to be an array:
private $Queue = array(); //Init
, but at the end of the function you are setting it to an object (named $newQueue):
public function invert() //Reverts the Queue
{
$newQueue = new Queue();
for ($i = $this->length() - 1;$i>=0;$i--)
{
$newQueue->add($this->first());
$this->remove();
}
$this->Queue = $newQueue;
}
You can solve this in one of two ways:
set $this->Queue to $newQueue->Queue (you probably have to make it a non-private variable)
learn how to invert an array in place instead of creating a temporary array
Here is solid solution for the invert method. I hope this helps.
//Reverts the Queue
public function invert() {
$newQueue = array();
for ($i = 0; $i < count($this->Queue) + 1; $i++) {
$newQueue[$i] = $this->Queue[count($this->Queue) - 1 - $i];
echo $newQueue[$i] . '<br/>';
}
}
I'm making a mp3/steaming radio with MVC, where I'm trying to load an URL from a array.
I have a radio class:
public class Radio
{
private var titel:String;
private var url:URLRequest;
private var cover:Bitmap;
public function Radio(titel:String, url:URLRequest, cover:Bitmap)
{
this.titel = titel;
this.url = url;
this.cover = cover;
}
public function getTitel():String {
return titel;
}
public function getURL():URLRequest {
return url;
}
public function getCover():Bitmap {
return cover
}
}
In the controller i have this:
public function selectRadio(radio:Radio):void{
model.selectRadio(radio);
}
In view I have the button with the eventlistner:
radio.addEventListener(MouseEvent.CLICK, function():void {
controller.selectRadio(model.getRadio(0));
});
And finally in the model i have:
private var radio:Radio = new Radio("P3", new URLRequest("http://live-icy.gss.dr.dk:80/A/A05L.mp3"), drp3);
private var radioArray:Array = new Array(radio);
private var r:Number;
public function selectRadio(radio:Radio):void {
var s:Sound = new Sound();
var chan:SoundChannel = s.play();
s.load();
trace("radio");
}
public function getRadios():Array {
return radioArray;
trace("All radio channels collected");
}
public function getRadio(radioNumber:int):Radio {
r = radioNumber;
return radioArray[radioNumber];
trace("Actual radio collected");
}
The problem is in the selectRadio function. I don't know how to load the URL in the arrays. It should be s.load(--something in here--); The reason why I'm doing this, is because I want to have multiple radio stations.
Hope you can help :)
var s:Sound = new Sound(radio.getURL());
var chan:SoundChannel = s.play();
load function will be called automatically by the constructor, also don't forget to stop previous SoundChannel.
and here: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html you will find everything about Sound
I've seen this kind of thing described in various examples showing how to create a REST service which takes arrays or a list of objects as part of the URL.
My question is, how to implement this using RESTeasy?
Something like the following would be how i would assume this to work.
#GET
#Path("/stuff/")
#Produces("application/json")
public StuffResponse getStuffByThings(
#QueryParam("things") List<Thing> things);
Create a StringConverter and a use a wrapper object. Here is a quick and dirty example:
public class QueryParamAsListTest {
public static class Thing {
String value;
Thing(String value){ this.value = value; }
}
public static class ManyThings {
List<Thing> things = new ArrayList<Thing>();
ManyThings(String values){
for(String value : values.split(",")){
things.add(new Thing(value));
}
}
}
static class Converter implements StringConverter<ManyThings> {
public ManyThings fromString(String str) {
return new ManyThings(str);
}
public String toString(ManyThings value) {
//TODO: implement
return value.toString();
}
}
#Path("/")
public static class Service {
#GET
#Path("/stuff/")
public int getStuffByThings(
#QueryParam("things") ManyThings things){
return things.things.size();
}
}
#Test
public void test() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getProviderFactory().addStringConverter(new Converter());
dispatcher.getRegistry().addSingletonResource(new Service());
MockHttpRequest request = MockHttpRequest.get("/stuff?things=a,b,c");
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
Assert.assertEquals("3", response.getContentAsString());
}
}
I think you can also use a StringParamUnmarshaller
I had some luck with this, using Collection rather than List. I was unable to make a StringConverter for List work.
#Provider
public class CollectionConverter implements StringConverter<Collection<String>> {
public Collection<String> fromString(String string) {
if (string == null) {
return Collections.emptyList();
}
return Arrays.asList(string.split(","));
}
public String toString(Collection<String> values) {
final StringBuilder sb = new StringBuilder();
boolean first = true;
for (String value : values) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append(value);
}
return sb.toString();
}
}
I did the toString from my head. Be sure to write unit tests for it to verify. But of course, everything is easier and clearer when you use Guava. Can use Joiner and Splitter. Really handy.
Just use a wrapper on its own, no need for anything else.
In your endpoint
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Path("/find")
#GET
MyResponse find(#QueryParam("ids") Wrapper ids);
And you wrapper looks like this :
public class Wrapper implements Serializable {
private List<BigInteger> ids = Collections.emptyList();
public String toString() {
return Joiner.on(",")
.join(ids);
}
public List<BigInteger> get() {
return ids;
}
public Wrapper(String s) {
if (s == null) {
ids = Collections.emptyList();
}
Iterable<String> splitted = Splitter.on(',')
.split(s);
Iterable<BigInteger> ids = Iterables.transform(splitted, Functionz.stringToBigInteger);
this.ids = Lists.newArrayList(ids);
}
public Wrapper(List<BigInteger> ids) {
this.ids = ids;
}
}