I'm having some trouble creating some custom web services in Magento. I'm trying to get the module configured properly and I can't seem to make the web services I've defined in the api.xml file show up under the user role setup in the admin area.
I've defined a custom module in app/etc shown here
ctp_GiftCards.xml:
<?xml version="1.0"?>
<config>
<modules>
<ctp_GiftCards>
<active>true</active>
<codePool>local</codePool>
</ctp_GiftCards>
</modules>
</config>
The module code is located in app/local/ctp/GiftCards/
Here is an example of the etc/api.xml:
<?xml version="1.0"?>
<config>
<api>
<resources>
<GiftCards translate="title" module="ctp_GiftCards">
<title>GiftCard webservices</title>
<acl>GiftCards/GiftCard</acl>
<methods>
<update translate="title" module="ctp_GiftCards">
<title>updates a giftcard account</title>
</update>
</methods>
<faults module="ctp_GiftCards">
<invalid_data>
<code>100</code>
<message>giftcard data invalid</message>
</invalid_data>
<card_pool_error>
<code>101</code>
<message>card pool for entry not updated</message>
</card_pool_error>
<cache_error>
<code>102</code>
<message>cache not reset</message>
</cache_error>
</faults>
</GiftCards>
</resources>
<acl>
<resources>
<GiftCards translate="title" module="ctp_GiftCards">
<title>GiftCards</title>
<sort_order>6</sort_order>
<GiftCard translate="title" module="ctp_GiftCards">
<title>GiftCard</title>
<update translate="title" module="ctp_GiftCards">
<title>Update</title>
</update>
</GiftCard>
</GiftCards>
</resources>
</acl>
</api>
</config>
and the etc/config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<ctp_GiftCards>
<version>0.1.0</version>
</ctp_GiftCards>
</modules>
<global>
<models>
<GiftCard>
<class>CTP_GiftCards_Model</class>
</GiftCard>
</models>
</global>
</config>
Any help would be much appreciated.
--edit--
I'm using mangeto pro 1.10
Don't use capital letter (GiftCards) in the name of xml tag inside the node. Moreover, your module's name contains both underscope (_) and capital letter (ctp_GiftCards) which will lead Magento to misunderstand.
Related
I'm newbie about validation on programming. Like Checking string and checking field input empty or not. Maybe anyone in here can share me about simple sample validation rule about string and checking field to me with XSLT. Thanks
First of all, XSLT is for XML transformations and if you want to do schema validations you should be looking at XSD validations. Having said that below is how you can use XSLT to validate a message and generate a payload.
Let's say you have a Payload like the below.
<Request>
<messages>
<message>
<id>123</id>
<name>Not Empty</name>
</message>
<message>
<id>234</id>
<name></name>
</message>
</messages>
</Request>
In the above payload, you want to check each message and check whether the name is empty or not. Inorder to validate this you can use XSLT. First create a XSLT as a LocalEntry in the local-entries directory. You can use the following content. (You can create your XSLT in the registry as well)
<?xml version="1.0" encoding="UTF-8"?>
<localEntry key="LOCAL_XSLT_NullCheck" xmlns="http://ws.apache.org/ns/synapse">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/">
<Response>
<!-- Iterating through message elements -->
<xsl:for-each select="//messages/message">
<message>
<messageID><xsl:value-of select="id/text()"/></messageID>
<xsl:choose>
<!-- Check if name is empty -->
<xsl:when test="boolean(name/text())">
<isEmpty>false</isEmpty>
</xsl:when>
<xsl:otherwise>
<isEmpty>true</isEmpty>
</xsl:otherwise>
</xsl:choose>
</message>
</xsl:for-each>
</Response>
</xsl:template>
</xsl:stylesheet>
</localEntry>
Next create a API to consume your request and to validate the payload and then to generate the response.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/xslt" name="TestAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<log level="full">
<property name="Message" value="Incoming Message"/>
</log>
<xslt key="LOCAL_XSLT_NullCheck"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Now once you invoke the API with the aforementioned message. You should see the following response.
<Response xmlns="http://ws.apache.org/ns/synapse">
<message>
<messageID>123</messageID>
<isEmpty>false</isEmpty>
</message>
<message>
<messageID>234</messageID>
<isEmpty>true</isEmpty>
</message>
</Response>
You ca read more on XSLT mediator from here. You can also consider using FastXSLT Mediator as well based on your requirement. Read more on XSLT from here.
I need to remove the attribute tags without any value in an xml file using ant script
Below is the XML I have:
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>DoNothingTest</members>
<name>ApexClass</name>
</types>
<types>
</types>
<types>
</types>
<types>
</types>
<types>
</types>
<version>42.0</version>
</Package>
All the tags that does not have a nesting tag or value should be removed from this xml . The output should look like below:
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>DoNothingTest</members>
<name>ApexClass</name>
</types>
<version>42.0</version>
</Package>
How can I achieve this using ANT script?
I am using the below ant script to perform the job, however, it trims only one occurence of 'types' tag.
<!--Format the generated XML file -->
<target name="formatXML" depends="generatePackage.xml">
<property name="final-xml.file" value="temp/src/package.xml"/>
<for param="src-xml.absolute-path" list="${final-xml.file}">
<fileset dir="temp/src/" includes="*.xml"/>
<sequential>
<replaceregexp file="${final-xml.file}"
flags="s"
match="\s*(?:<\/([a-z]+)>)(\s*<\1>)"
replace=""/>
</sequential>
</for>
</target>
How to iterate over the xml file and replace all occurences of 'types' tags?
You can invoke an XSLT transformation from Ant using the XSLT ant task. A stylesheet to remove empty <types> elements in namespace http://soap.sforce.com/2006/04/metadata consists of a boilerplate identity rule to copy all elements unchanged, plus the rule
<xsl:template match="x:types[not(*) and not(text()[normalize-space()])]"
xmlns:x="http://soap.sforce.com/2006/04/metadata"/>
Currently I use Doctrine2 with value object, it's working great. The problem when I use value object with only one field, for example:
$this->repository->findBy(array('email' => 'name#domain.com')); //This is not working
$this->repository->findBy(array('email.email' => 'name#domain.com')); //This is work great
The question is, how to make $this->repository->findBy(array('email' => 'name#domain.com')); working?
This is my doctrine mapping
User.orm.xml
<!-- User.orm.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"
xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping">
<entity name="Domain\User\Entity\User" table="users" repository-class="Infrastructure\User\Repository\UserRepository">
<id name="id" type="guid">
<generator strategy="UUID"/>
</id>
<embedded name="email" class="Shared\ValueObject\Email" use-column-prefix="false" />
</entity>
</doctrine-mapping>
Email.orm.xml
<!-- Email.orm.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<embeddable name="Shared\ValueObject\Email">
<field name="email" type="string" length="80" />
</embeddable>
</doctrine-mapping>
Thank you for your help, and sorry for my bad english.
Unfortunately according to code this is not possible. Field name always be
$property . "." . $fieldMapping['fieldName'];
I have followed the exact steps from the official documentation, but I still cannot get my app to start using the custom voice command. The steps are followed are:
1 Add new string resource for custom voice command in strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Hello World!</string>
<string name="glass_voice_trigger">start example</string>
</resources>
2 Create a new XML file for voice startup definition:
<?xml version="1.0" encoding="utf-8"?>
<trigger keyword="#string/glass_voice_trigger" />
3 Request proper permissions in AndroidManifest.xml:
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
4 The manifest part looks as follows:
<service
android:name="pl.infoshare.sample.helloworld.HelloWorldService"
android:icon="#drawable/ic_lap"
android:label="#string/app_name"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voice_trigger_start" />
</service>
Still, I am not able to start the app using the voice command. If I change to one of the predefined voice commands the app shows up on the timeline and I can start it using the voice command. Did I miss anything?
Looking through the question, I didn't see anything jump out at me as incorrect. So, I created a small sample GDK project that is launched with a custom voice command, and runs just fine on my XE17.1 device. (Bonus, it demos a low-frequency LiveCard!)
Try pulling down my sample from GitHub, and see if you can launch it with the command:
'OK Glass, start my awesome app'
Below are some of the relevant bits.
AndroidManifest.xml:
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.DeviceDefault">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:immersive="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name=".LowFreqLiveCardService"
android:enabled="true"
android:exported="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<intent-filter>
<action android:name=
"com.google.android.glass.action.VOICE_TRIGGER"/>
</intent-filter>
<meta-data android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voice_trigger"/>
</service>
</application>
</manifest>
res/xml/voice_trigger.xml:
<?xml version="1.0" encoding="utf-8"?>
<trigger keyword="#string/custom_keyword" />
res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Low Freq Demo</string>
<string name="heart_rate">Heart Rate</string>
<string name="custom_keyword">start my awesome app</string>
</resources>
Here's a link to the voice command documentation, it still provides instructions on using custom voice commands. And, from my testing, they still do work.
Custom voice commands require, since a couple of versions ago, the aproval from google. You can send a request for that aproval from the glass developer site.
Review this.
Need help to display a sample card in the glass timeline(refer image). All i need is to launch the card when one taps when "ok glass" is displayed and scroll to view the card(image 2), the same via voice command also does not work.
I tried launching the same activity via adb shell it works perfectly fine, also i added an intent filter with MAIN/LAUNCHER category to the activity - it runs. I referred this link for this POC but nothing like the image is being displayed. Please help as to where am i going wrong - TIA
Activity:
package de.androidzeitgeist.glass.helloworld.immersion;
import android.app.Activity;
import android.os.Bundle;
import com.google.android.glass.app.Card;
public class HelloWorldActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Card card = new Card(this);
card.setText("Hello world!");
card.setFootnote("android.com");
setContentView(cardroid.getView());
}
}
Manifest File:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.androidzeitgeist.glass.helloworld.immersion"
android:versionCode="1"
android:versionName="1.0" >
<application
android:allowBackup="true"
android:icon="#drawable/helloworld_icon"
android:label="#string/app_name" >
<activity
android:name="de.androidzeitgeist.glass.helloworld.immersion.HelloWorldActivity"
android:icon="#drawable/helloworld_icon"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="#xml/voice_trigger" />
</activity>
</application>
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
</manifest>
voice_trigger.xml
<?xml version="1.0" encoding="utf-8"?>
<trigger keyword="#string/show_hello_word" />
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">HelloWorldImmersion</string>
<string name="hello_world"></string>
<string name="show_hello_word">show hello world</string>
</resources>
If you are using an unregistered voice command, your manifest.xml must include
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
See https://developers.google.com/glass/develop/gdk/starting-glassware for more details about using registered commands and unlisted commands and Why is my voice command missing from the ok glass menu in XE16? for some clarification and examples.